Project: WASC Threat Classification

Threat Type: Attack

Reference ID: WASC-26

 

HTTP Request Smuggling

HTTP Request Smuggling is an attack technique that abuses the discrepancy in parsing of non RFC compliant HTTP requests between two HTTP devices (typically a front-end proxy or HTTP-enabled firewall and a back-end web server) to smuggle a request to the second device “through” the first device. This technique enables the attacker to send one set of requests to the second device while the first device sees a different set of requests. In turn, this facilitates several possible exploitations, such as partial cache poisoning, bypassing firewall protection and XSS.

 

While it’s impossible to provide a comprehensive overview of HTTP Request Smuggling in this scope (there are many technical details and variants involved), we will outline the textbook example to convey the concept. The reader is referred to [1] for full details.

 

The textbook example ([1]) involves sending a set of HTTP requests to a system comprising of a web server (for www.target.site) and a caching proxy server. The goal of the attack is to force the proxy to cache the contents of the page http://www.target.site/~attacker/foo.html for the URL http://www.target.site/~victim/bar.html The attack involves sending an HTTP POST request with multiple Content-Length headers, which the RFC [2] forbids. While disallowed, the vast majority of web servers and proxy servers support this, each in its own fashion. The attack exploits the difference in this “support”. For instance, assume that the proxy uses the last header, while the web server uses the first header.

The attacker sends

 

POST http://www.target.site/somecgi.cgi HTTP/1.1
Host: www.target.site
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
Content-Length: 45

GET /~attacker/foo.html HTTP/1.1
Something: GET http://www.target.site/~victim/bar.html HTTP/1.1
Host: www.target.site
Connection: Keep-Alive

 

 

From the proxy’s perspective, it sees the header section of the first (POST) request, it then uses the last Content-Length header (which specifies a body length of 45 bytes) to know what body length to expect. It then reads the body and sends the web server the first request as following:

 

POST http://www.target.site/somecgi.cgi HTTP/1.1
Host: www.target.site
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
Content-Length: 45

GET /~attacker/foo.html HTTP/1.1
Something:

 

The web server sees the first request (POST), inspects its headers, uses the first Content-Length header, and interprets the first request as

 

POST http://www.target.site/somecgi.cgi HTTP/1.1
Host: www.target.site
Connection: Keep-Alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
Content-Length: 45

 

Note the empty body. The web server answers this request, and it has one more partial request in the queue:

 

GET /~attacker/foo.html HTTP/1.1
Something:

 

Since this request is incomplete (a double CR+LF has not been received, so the HTTP request header section is not yet complete), the web server remains in a wait state. The proxy now receives the web server’s first response, forwards it to the attacker and proceeds to read from its TCP socket:

 

GET http://www.target.site/~victim/bar.html HTTP/1.1
Host: www.target.site
Connection: Keep-Alive

 

From the proxy’s perspective, this is the second request, and whatever the web server will respond with, will be cached by the proxy for http://www.target.site/~victim/bar.html. The proxy forwards this request to the web server. It is appended to the end of the web server’s queue, which now looks as following:

 

GET /~attacker/foo.html HTTP/1.1
Something: GET http://www.target.site/~victim/bar.html HTTP/1.1
Host: www.target.site
Connection: Keep-Alive

 

 

The web server finally has a full second request to process. The web server interprets the request stream as containing an HTTP request for http://www.target.site/~attacker/foo.html (in the HTTP request above, the “Something” HTTP header has no meaning according to the HTTP RFC, and thus is ignored by the web server), and thus the content of the page http://www.target.site/~attacker/foo.html is returned. The net result – the web server returns a second response comprising of the content of the page http://www.target.site/~attacker/foo.html, and the proxy caches this content under the URL http://www.target.site/~victim/bar.html.

 

Hence, partial web cache poisoning was achieved. “Partial” because as the reader may note, the attacker is not in full control over the cached content. The attacker has no direct control over the returned HTTP headers, and more importantly, the attacker has to use an existing (and cacheable) page in the target web site for his/her content (in the above case, it is http://www.target.site/~attacker/foo.html).

The above example only demonstrated web cache poisoning. However, as shown in [1], HTTP Request Smuggling can be used to conduct cross site scripting attacks, bypass HTTP-enabled firewall and steal sessions and sensitive data (pages).

 

http://projects.webappsec.org/w/page/13246928/HTTP%20Request%20Smuggling