I'm almost newby to nodejs. I'm working on a small nodejs micro-service and its running well. But as per recent requirement this service need to support HTTP/1.1 pipeline. But I'm failing to find in nodejs doc that how to enable/support that.
Please guide me find appropriate doc/module/resource to implement HTTP/1.1 pipeline.
Thanks.
Comments from #shaochuancs and #Helen are about nodejs http client.
If you need a server implementation of HTTP pipeline that depends entirely on the the nodejs core library.
HTTP server-side pipelining support is built-in and already OK in nodejs (I've just made the tests on tested on v5.5.0 v7.0.9 and v6.2.1).
To test pipelining support simply chain two HTTP request in the same tcp/ip connection. You can do it using telnet or netcat (nc).
# telnet, connecting to port 80, chaining 2 requests on /login
# for host foo.com
(echo -en "GET /login HTTP/1.1\nHost: foo.com\nConnection: keep-alive\n\nGET /login HTTP/1.1\nHost: foo.com\n\n"; sleep 10) | telnet localhost 80
# same thing using printf and netcat
printf "GET /login HTTP/1.1\r\nHost: foo.com\r\nConnection: keep-alive\r\n\r\nGET /login HTTP/1.1\r\nHost: foo.com\r\n\r\n" | nc -q 10 localhost 80
Then count the number of responses, you should get 2 (or 1 if pipelining is not supported). Search for 'HTTP/1.1 200 OK' in the output.
Related
I am managing a site hosted on aws ec2 using nginx. To avoid threats continuously monitoring nginx logs ( access.log & error.log). Though many threats are well managed by tweaking nginx.conf, but this specific one I am not even able to figure out how attacker manage to send such request.
access.log
xx.xxx.xx.xxx - - [18/Aug/2021:09:04:13 +0000] "GET http://xxxxxxxxx.com/ HTTP/1.1" 200 1400 "-" "Go-http-client/1.1"
In above case let's say name of my website is "h ttp://abc-xyz-1234.com", attacker is passing url in path (i.e. http://xxxxxxxxx.com/ ), and nginx responding with "200". I am still scratching my head how was request made and what was responded with 1400 of bytes ( response length still much lesser than website response site for path "/" ).
As I believe its not possible through browser, I tried to simulate using curl but it wouldn't work.
it is considered 2 separate request to curl
curl -A Mozilla h ttp://abc-xyz-1234.com/ http://xxxxxxxxx.com
invalid domain
curl -A Mozilla h ttp://abc-xyz-1234.comhttp://xxxxxxxxx.com
it will hit host with path /http://xxxxxxxxx.com and get rejected. Attacker is manage to send it without prefix "/" and thats what trying to simulate
curl -A Mozilla h ttp://abc-xyz-1234.com/http://xxxxxxxxx.com
You can use --request-target for this:
curl -A Mozilla http://abc-xyz-1234.com --request-target http://xxxxxxxxx.com
I have a Tornado server running on some port
And if I make a request via browser to non existing url, Tornado prints:
WARNING:tornado.access:404 POST /some_url/ (MY.REAL.IP) 0.64ms python
But I noticed another 404 error done via localhost:
WARNING:tornado.access:404 POST /some_url/ (127.0.0.1) 0.64ms python
Is it possible in theory, that this request was done by some "cool hacker" from remote server using curl --resolve or something?
The only way this address should be spoofable would be if you set xheaders=True in your HTTPServer constructor. If you use xheaders=True, you should also be using a frontend proxy that sanitizes headers appropriately so it will not allow X-Real-IP headers from outside sources.
I know people are scanning my server to use it as an open proxy. I am running nodejs through an express framework on an amazon cloud machine. I am using iptables to port forward port 80 to 8080 so I can avoid running it as a root user.
GET http://www.baidu.com/ 200 1.484 ms - 6482
GET http://yahoo.com/ 200 1.557 ms - 6482
GET /css/index.css 304 1.310 ms - -
Obviously yahoo and baidu are not part of my domain so shouldn't they return 404?
When I use
curl --proxy <<mywebsite>> http://yahoo.com
I get the html for my root page instead of yahoo. Why is this not 404ing?
I want to verify that my web application does not have a path traversal vulnerability.
I'm trying to use curl for that, like this:
$ curl -v http://www.example.com/directory/../
I would like the HTTP request to be explicitly made to the /directory/../ URL, to test that a specific nginx rule involving proxy is not vulnerable to path traversal. I.e., I would like this HTTP request to be sent:
> GET /directory/../ HTTP/1.1
But curl is rewriting the request as to the / URL, as can be seen in the output:
* Rebuilt URL to: http://www.example.com/
(...)
> GET / HTTP/1.1
Is it possible to use curl for this test, forcing it to pass the exact URL in the request? If not, what would be an appropriate way?
The curl flag you are looking for is curl --path-as-is .
I'm not aware of a way to do it via curl, but you could always use telnet. Try this command:
telnet www.example.com 80
You'll see:
Trying xxx.xxx.xxx.xxx...
Connected to www.example.com.
Escape character is '^]'.
You now have an open connection to www.example.com. Now just type in your command to fetch the page:
GET /directory/../ HTTP/1.1
And you should see your result. e.g.
HTTP/1.1 400 Bad Request
You can use an intercepting proxy to capture a request to your application and repeat the request with parameters changed, such as the raw URL that is requested from the application.
The free version of Burp Suite will allow this using the Repeater.
However, there are alternatives that should also allow this such as Zap, WebScarab and Fiddler2.
If somebody accesses my server via http (i. e. not https) then I redirect GET requests to the https version.
But I don't know what to do with POST and PUT because I cannot redirect them (the browser does a GET on redirect I believe).
I should return an error code. What HTTP error code should I return?
Typically, you would return a 403 - Forbidden. The general description of this is "The server understood the request, but refuses to authorize it." which would fit your situation.
Technically right answer is to use 403.4 but substatuses it's a IIS only feature and nginx doesn't support it.
So I've prefer to return 418 "I'm a teapot" or 451 "Unavailable For Legal Reasons" (because it's not legal to use plain-text http anymore, haha, just joking :)), this statuses quite exotic and should trigger client to figure out what going on.
nginx has an option to return status with text like
# cat /etc/nginx/conf.d/default.conf
server {
listen 80 default_server;
location / {
add_header Content-Type text/plain;
return 418 "TLS REQUIRED";
}
}
# curl -v http://localhost/
* About to connect() to localhost port 80 (#0)
* Trying ::1...
* Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost
> Accept: */*
>
< HTTP/1.1 418
< Server: nginx/1.16.1
< Date: Sat, 15 Feb 2020 07:13:20 GMT
< Content-Type: application/octet-stream
< Content-Length: 12
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
TLS REQUIRED
But browsers like Chrome or Firefox can't handle this right, Chrome says ERR_INVALID_RESPONSE and Firefox says "File not found" and this behavior doesn't solve our goal.
So I've stay with just returning status 418.
http://www.ietf.org/id/draft-ietf-httpbis-p2-semantics-18.txt explains HTTP response codes. If you want an error code, just return a 404 if requests cannot be serviced at that URL.
7.4.5. 404 Not Found
The server has not found anything matching the effective request URI.
No indication is given of whether the condition is temporary or
permanent. The 410 (Gone) status code SHOULD be used if the server
knows, through some internally configurable mechanism, that an old
resource is permanently unavailable and has no forwarding address.
This status code is commonly used when the server does not wish to
reveal exactly why the request has been refused, or when no other
response is applicable.