HTTP Request Smuggling

Parsing of Content-Length and Transfer-Encoding headers leads to messing with boundaries of requests

Note: This page was made as notes while learning HTTP Request Smuggling myself, using the Portswigger resources and labs

Description

Portswigger explaining what HTTP Request Smuggling is

HTTP Request Smuggling is possible when the parsing of Content-Length and Transfer-Encoding: chunked headers are different for front-end and back-end servers.

Types

Name
Front-end
Back-end

CL.TE

Content-Length

Transfer-Encoding

TE.CL

Transfer-Encoding

Content-Length

TE.TE

Transfer-Encoding

Transfer-Encoding

TE.TE: Transfer-Encoding front-end, Transfer-Encoding backend, but one can be tricked into using Content-Length by obfuscating Transfer-Encoding header

Impact

  • Smuggle HTTP in front of the next request by someone else

  • Smuggle another request through front-end to back-end to bypass filters

Types

CL.TE

Portswigger lab for practicing CL.TE type

The front-end uses Content-Length: 6 which sends the whole body (0\r\nG\r) to the back-end. The back-end uses Transfer-Encoding: chunked which will read the first 0 and then stop because this signals the end. When anyone now does another request to the back-end, the G is already sent and prepended to it making the request GPOST if it was a POST before.

TE.CL

Portswigger lab for practicing TE.CL type

Burp Suite automatically fixes Content-Length, but it only is correct for the back-end after splitting the request. So turn off "Update Content-Length" setting in Repeater

The front-end takes Transfer-Encoding: chunked, so it sends the whole body to the back-end. Then the back-end takes Content-Length: 4 and only reads the first 61\r bytes. The back-end server responds that the request does not contain the right parameters but this does not matter. Next, the GPOST is also sent to the back-end and when anyone now makes another request to the back-end, it will respond with the already done GPOST answer.

TE.TE

Portswigger lab for practicing TE.TE type

Ways to confuse front-end and back-end:

Depending on whether the front-end or back-end uses the Transfer-Encoding, it can become either CL.TE or TE.CL

Solution to the lab:

First tested TE.CL, and with double Transfer-Encoding header got a proxy timeout. This could be because one of the servers is waiting for more bytes, but not getting them.

If the front-end uses Content-Length: 4 it only sends 61\r to the back-end. If the back-end then uses Transfer-Encoding it would see the 61 and wait for 97 more bytes, which it is not getting from the proxy causing a timeout. This would mean it is a CL.TE type instead. Trying the same with a CL.TE payload confirms this by solving the lab:

Confirming Request Smuggling

Portswigger explaining how to config this attack

CL.TE

Portswigger lab for practicing CL.TE and confirming it seeing a different response

Specify the requested location with GET /404, which will append cookies, etc. to the request making a GET CSRF

TE.CL

Portswigger lab for practicing TE.CL and confirming it seeing a different response

Same idea as CL.TE, with x= in the body because the 0 will also be prepended to the next request. A lonely 0 in the next request would not be a valid header, so it needs to be the body.

Exploiting

Portswigger explaining how to exploit a HTTP Request Smuggling attack in a practical scenario

CL.TE

Portswigger lab for performing CSRF using CL.TE

We can provide a complete HTTP request to prepend the next request by any victim. We can bypass front-end filters by sending an allowed request in the attack request, and an unauthorized request in the normal request that we smuggle. To make sure the headers from the original request don't interfere we can put it in a body like seen below:

TE.CL

Portswigger lab for performing CSRF using TE.CL

Same as confirming TE.CL

Leaking headers

Portswigger lab for leaking internal headers with HTTP Request Smuggling

Leak data in comment content. Put comment= last to make the next request get appended and read as part of the comment. Make sure to use long Content-Length but not too long.

Now the page shows the X-mxqMOU-Ip header

Use this header like before to make a request look like it was valid from the front-end

Leaking cookies from other users

Portswigger lab for leaking cookies from other users

This type of attack can also be used to leak Cookies from requests from other users, by storing the data is a comment for example. The Content-Length needs to be perfect though, to find the entire cookie

Set headers on victim request to get XSS

Portswigger lab for changing the request from a victim to return XSS

Last updated