HTTP test code in C using POST request returns 405 status code - c

I have written a test code that first connects to a web server. It then requests a page, which has a login form, using GET. The GET works and a 200 status code is returned from the web server. After retrieving the page, I attempt to send a POST request to send some log in information but instead receive a 405 METHOD_NOT_ALLOWED status code in return.
Here is the code for sending the GET:
char data[273] = "GET /login HTTP/1.1\r\nHost: www.minecraft.net\r\nUser-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)\r\nAccept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7\r\nCache-Control: no-cache\r\nAccept-Language: de,en;q=0.7,en-us;q=0.3\r\nReferer: http://web-sniffer.net/\r\n\r\n";
if ((val = send(sockfd, &data,272,0)) == -1){
perror("send");
}
And here is the code containing the POST command, username and password are changed so no personal information is given out:
char data2[405] = "POST /login HTTP/1.1\r\nHost: www.minecraft.net\r\nConnection: close\r\nUser-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)\r\nAccept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7\r\nCache-Control: no-cache\r\nAccept-Language: de,en;q=0.7,en-us;q=0.3\r\nReferer: http://web-sniffer.net/\r\nContent-type: application/x-www-form-urlencoded\r\nContent-length: 38\r\n\r\nusername=ausername&password=apassword";
if ((val = send(sockfd, &data2,404,0)) == -1){
perror("send");
}
To make the packets readable:
GET /login HTTP/1.1[CRLF]
Host: www.minecraft.net[CRLF]
User-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no-cache[CRLF]
Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
Referer: http://web-sniffer.net/[CRLF]
[CRLF]
And the POST packet:
POST /login HTTP/1.1[CRLF]
Host: www.minecraft.net[CRLF]
Connection: close[CRLF]
User-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no-cache[CRLF]
Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
Referer: http://web-sniffer.net/[CRLF]
Content-type: application/x-www-form-urlencoded[CRLF]
Content-length: 38[CRLF]
[CRLF]
username=ausername&password=apassword
As you may notice, the User-Agent is Web-sniffer as I used web-sniffer.net to make these packets, which worked on their website as the POST command there returned a 302 FOUND status code.
I am wondering why this behavior is observed here when the exact same packets worked on web-sniffer.net, yet don't work here.

Related

Missing Csrf token cookie

I'm relatively new to CakePHP (v3.7). I have an application in which I'm getting a "Missing Csrf Token Cookie" error.
In Application.php, I have:
$options = []; // I'm fine with the default options.
$csrf = new CsrfProtectionMiddleware($options);
$middlewareQueue->add($csrf);
The form page has a hidden form element with the _csrfToken in it.
I'm confused as to why it's not being found on the POST?
Digging further, I found that in CsrfProtectionMiddleware.php, the _validateToken() function below behaves as follows:
$cookies is null (there are no cookies set.)
thus, $cookie is null.
$post actually contains the content of the _csrfToken parameter from the hidden parameter on the page. However the function never looks at it. Because $cookie is null,
the if(!$cookie) statement causes an InvalidCsrfTokenException to be thrown.
protected function _validateToken(ServerRequest $request)
{
$cookies = $request->getCookieParams();
$cookie = Hash::get($cookies, $this->_config['cookieName']);
$post = Hash::get($request->getParsedBody(), $this->_config['field']);
$header = $request->getHeaderLine('X-CSRF-Token');
if (!$cookie) {
throw new InvalidCsrfTokenException(__d('cake', 'Missing CSRF token cookie'));
}
if (!Security::constantEquals($post, $cookie) && !Security::constantEquals($header, $cookie)) {
throw new InvalidCsrfTokenException(__d('cake', 'CSRF token mismatch.'));
}
}
}
Obviously, the middleware is expecting an actual cookie, in addition to a hidden parameter. Where is this cookie set (or supposed to be set?)
Update:
I checked on the browser side. The cookie is being set, but the browser isn't returning it on the POST request.
Here's CakePHP's RESPONSE to the original GET request to populate the page:
Connection: Keep-Alive
Content-Length: 3013
Content-Type: text/html; charset=UTF-8
Date: Wed, 08 May 2019 23:07:31 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.33 (Unix) PHP/7.1.1
Set-Cookie: csrfToken=b553dd2e06e57f6d514ee41a120e1c60084adafddfbaa6f72db1f7f590fcf50143876ac817d29d6f1cf9a786031d6235ba21e265b9d3b2a0ee4535854f048b66; path=/webroot/
X-Powered-By: PHP/7.1.1
Note the csrfToken cookie.
... and here's the POST that the browser sends back with the form data
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 184
Content-Type: application/x-www-form-urlencoded
DNT: 1
Host: *************
Origin: ****************
Pragma: no-cache
Referer: ***************
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36
Query String Parameters
redirect: /Users/login
Form Data
_method: POST
_csrfToken: b553dd2e06e57f6d514ee41a120e1c60084adafddfbaa6f72db1f7f590fcf50143876ac817d29d6f1cf9a786031d6235ba21e265b9d3b2a0ee4535854f048b66
username: xxxxxxxxxx
password: xxxxxxxxxx
Note that it's sending back the hidden form parameter _csrfToken, but NOT the cookie.
Thanks for any help...
This turned out to be a problem with the DOCUMENT_ROOT directory setting in Apache. It was set to the parent directory of webroot, instead of to webroot itself. When I changed it everything worked.

AngularJs $http.post() request is not working properly

AngularJs $http.post() request is not working properly
I want to store one task to my db. If amount of data in assignedMember is more than 175 it will not send got 404 error but If amount of data in assignedMember is less than 175 it will send success and store my db. Any idea about this. I dont what wrong with me. Please help me thank you
This is my json data
$scope.task=
{
"title": "My Title",
"description": "My Description",
"assignedMember": [
{
"userId": "51b701dae4b0dd92df2c32d1",
"status": "ASSIGNED"
},
{
"userId": "52de0811e4b04615ce7ed6bd",
"status": "ASSIGNED"
},
{
"userId": "559f8e97e4b0a5cdcd66bb76",
"status": "ASSIGNED"
},
.
.
.
.
.
.etc upto 500 data
]
}
This is my post request api
var responsePromise = $http.post("api/tasks",$scope.task);
responsePromise.success(function(data, status, headers, config) {
alert("Data created successfully");
});
responsePromise.error(function(data, status, headers, config) {
alert("Error")
});
If assigned member size is more than 175 or Content Length in browser is greater than 24580 when i send this json i got 404 error
If assigned member size is less than 175 or Content Length in browser is lesser than 10080 when i send this json it will success
If i getting 404 error my browser console is like this
Request header
-------------
Host: localhost
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: application/json, text/plain, /
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json;charset=utf-8
Referer: http://localhost/login.do
Content-Length: 24580
Response header
--------------
Connection: close
Content-Encoding: gzip
Content-Type: text/html
Date: Thu, 15 Dec 2016 14:21:56 GMT
Server: nginx/1.10.1
Transfer-Encoding: chunked
Is it any restriction in my nginx server? Please help me
Post request have no restriction rit? and get request is limited to 2048KB
Actually I am sending via post so what problem i am facing?
Connection: close, I think your server have not accept large count of data.
nginx "fails fast" when the client informs it that it's going to send a body larger than the client_max_body_size by sending a 413 response and closing the connection.
Most clients don't read responses until the entire request body is sent. Because nginx closes the connection, the client sends data to the closed socket, causing a TCP RST.
If your HTTP client supports it, the best way to handle this is to send an Expect: 100-Continue header. Nginx supports this correctly as of 1.2.7, and will reply with a 413 Request Entity Too Large response rather than 100 Continue if Content-Length exceeds the maximum body size.
Referred from

CORS issue with angular $http.post - successful requests result in errors with status 0

I'm using angular to POST to an authentication endpoint; on the server side, I can see the request succeed, and proper CORS headers are set. Angular's origin is http://localhost:9000
On the server side, preflight OPTIONS requests always get a 200 back, so that seems OK.
On the client side, the $http.post always fails with an error code of 0, which from other research suggests something is still wrong with CORS. I've read the spec and tried a number of other answers, yet something is still missing.
Angular POSTs like this:
$http({
method: 'POST',
url: 'http://localhost:3000/auth/login',
data: {
username: $scope.username,
password: $scope.password
}
})
.then(function (response) {
/* etc. etc. */
}, function (response) {
/* This always triggers, with response.status = 0 */
console.log("ERROR: " + response.data);
console.log("Status: " + response.status);
console.log("Status text: " + response.statusText);
console.log("Headers: " + response.headers);
$scope.error = 'Something went wrong...';
});
Using curl to debug what the server is sending back, this is it:
< HTTP/1.1 302 Found
< X-Powered-By: Express
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
< Access-Control-Allow-Headers: Origin, Content-Type, Accept, Authorization, Content-Length, X-Requested-With
< Access-Control-Allow-Credentials: true
< Set-Cookie: ua_session_token=(blahblah); Path=/
< Location: /
< Vary: Accept
< Content-Type: text/plain; charset=utf-8
< Content-Length: 23
< Date: Mon, 28 Dec 2015 15:08:17 GMT
< Connection: keep-alive
This is why I'm at a loss, as per the specification, the server seems to be doing the right thing?
Here's what the server gets from the client in terms of request headers:
HEADER host localhost:3000
HEADER content-type application/json;charset=UTF-8
HEADER origin http://localhost:9000
HEADER content-length 38
HEADER connection keep-alive
HEADER accept application/json, text/plain, */*
HEADER user-agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9
HEADER referer http://localhost:9000/
HEADER accept-language en-us
HEADER accept-encoding gzip, deflate
UPDATE tried something else with no luck, based on this post. It would seem Access-Control-Allow-Headers is case-sensitive, and angular is sending on the request accept, origin, content-type. I tweaked the server to parrot back the same, with no luck.
Alright, after applying my head to my keyboard for several hours, I've fixed it.
The answer seems to be that angular really doesn't like getting redirects in response to POST. When I changed the server endpoint to return just a plain auth token as text (the same token it was setting as a cookie anyway) rather than returning a redirect, the angular POST started working like a charm and falling through to the success handler.
Not sure I got deep enough into this to know why angular was behaving in that way; by playing around with it I found that if the redirect the server sent was to a nonexistent (404) URL that this could be replicated, EVEN IF the original POST returned that valid redirect.

Jersey Server Sent Events not working with Accept-Encoding gzip

I am using Jersey 2.17 for SSE - I have the demo working per the docs: https://jersey.java.net/documentation/latest/sse.html.
In my tests, it works fine with simple curl requests (curl --verbose "localhost:9000/api/broadcast"), but if I add -H 'Accept-Encoding: gzip, deflate' (to replicate my javascript code) it doesn't work (eventually times out with 'transfer closed with outstanding read data remaining'). I'm guessing that jersey says its GZIPed the response, but really it hasn't.
My real problem is that the AngularJS javascript code always adds this Accept-Encoding... header.
I'm looking for a solution that will either
Prevent Accept-Encoding: gzip, deflate' from being added as Request Header when initialising the EventSource() object
Setup Jersey to correctly handle/gzip the events sent to the client.
Update - I've noticed that if I close the EventOutput object in Java code that my events are all sent.
This is the console output when using curl:
curl --verbose "localhost:9000/api/broadcast" -H 'Accept-Encoding: gzip, deflate'
* Hostname was NOT found in DNS cache
* Trying ::1...
* connect to ::1 port 9000 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9000 (#0)
> GET /api/broadcast HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:9000
> Accept: */*
> Accept-Encoding: deflate, gzip
>
< HTTP/1.1 200 OK
* Server Apache-Coyote/1.1 is not blacklisted
< server: Apache-Coyote/1.1
< vary: Accept-Encoding
< content-encoding: deflate
< content-type: text/event-stream
< transfer-encoding: chunked
< date: Tue, 07 Apr 2015 20:35:42 GMT
< connection: close
<
* transfer closed with outstanding read data remaining
* Closing connection 0
curl: (18) transfer closed with outstanding read data remaining
For reference, my js code in my AngularJS app is:
$scope.sseSource = new EventSource('/api/ptt/1/status');
console.log( $scope.sseSource);
$scope.sseSource.onerror = function (event) {
console.log("onerror");
}
$scope.sseSource.onopen = function (event) {
console.log("onopen");
}
$scope.sseSource.onmessage = function (event) {
console.log("onmessage");
}

CORS - CakePHP does not accept AngularJS JSON-Request

I'm using CakePHP as backend and AngularJS as frontend, whereas front- & backend are in different domains so this is basically a CORS-situation.
Basically I'm trying to send the contents of a form to a Cake-API (later this is meant to do authentication part - but I'm failing earlier) via $http.post. So here is the code:
aeapBackend.login = function(username, password) {
return $http.post(
API_URL + 'api_mobile_user/login', {
test: username,
test2: password
}
);
};
Whereas the corresponding API in CakePHP looks like this:
function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(array('login'));
}
public function login() {
$this->response->header(array(
'Access-Control-Allow-Origin' => '*',
'Access-Control-Allow-Headers' => 'Content-Type'
)
);
$this->autoRender = false;
}
What happens next is that the preflight OPTIONS request ist done - which looks quite good to me:
Request Headers:
OPTIONS /api_mobile_user/login HTTP/1.1
Host: aeap.localhost
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://asf.localhost
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://asf.localhost/?username_input=hjk&password_input=hjgk&login_button=
Accept-Encoding: gzip,deflate,sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Response headers:
HTTP/1.1 200 OK
Date: Wed, 05 Nov 2014 15:29:00 GMT
Server: Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.5.15
X-Powered-By: PHP/5.5.15
Set-Cookie: CAKEPHP=j6st0hnq8ear2cc6psg56d6eu3; expires=Wed, 05-Nov-2014 19:29:00 GMT; Max-Age=14400; path=/; HttpOnly
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
But when the actual POST-request is done I get an status code 403:
XMLHttpRequest cannot load http://aeap.localhost/api_mobile_user/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://asf.localhost' is therefore not allowed access. The response had HTTP status code 403.
How can I avoid this? In my opinion I already enabled CORS support for Cake ['Access-Control-Allow-Origin']. It seems to me that AngularJS posts some additional informations whioch are not checked during the preflight and then rejected by the backend.
Used versions: CakePHP 2.5.3, AngularJS: 1.3.0
Thanks to Marvin Smit I was able to determine the reason for the behavior which was not connected to CORS are the headers. I set 'Access-Control-Allow-Origin' => '*'on web-server level so I was able to get a response which pointed to the security component of CakePHP.
I basically tried to send a POST-Reuqest to an API which did not expect that data should be posted to it. Therefore the access was denied. So I had to add $this->Security->csrfCheck = false to the beforeFilter:
function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(array('login'));
$this->Security->csrfCheck = false;
}
For what it's worth, the proper way to do this for Cakephp 3 is as follows
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(array('login'));
$this->eventManager()->off($this->Csrf);
}
Although, this is not recommended for AJAX requests. The following doc can help you more. CSRF And AJAX

Resources