HTTP request smuggling, basic CL.TE vulnerability

2 min read Easy PortSwigger
HTTP request smuggling
Contents

On this page

The lab

here is how portswigger describes it

This lab involves a front-end and back-end server, and the front-end server doesn't support chunked encoding. The front-end server rejects requests that aren't using the GET or POST method.

To solve the lab, smuggle a request to the back-end server, so that the next request processed by the back-end server appears to use the method GPOST.

The idea#

this is the standard cl.te setup, the front end trusts Content-Length and the back end trusts Transfer-Encoding. we send a body that the front end forwards whole by its length, but that the back end cuts short at a zero chunk, so whatever we place after that zero chunk is left on the connection as the start of the next request.

the twist that makes GPOST is that we leave behind just a single character, G. it sits at the very front of the connection, so when the next request arrives, its POST request line gets glued onto our G, and the two together read as GPOST. that is not a real method, so the back end returns an error about an unrecognised method, which is the visible proof that our smuggled letter got prepended to someone else's request.

Step 1 - Send the smuggle request#

we intercept a request and change it to this.

HTTP
POST / HTTP/1.1
Host: your-lab-id.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Transfer-Encoding: chunked

0

G
a

walking through it, the body is 0, a blank line, and then G, which comes to exactly 6 bytes, matching Content-Length: 6. the front end reads those 6 bytes as the body and forwards the whole request. the back end reads Transfer-Encoding: chunked, meets the 0 chunk, ends the request body there, and is left with the trailing G as the beginning of the next request on the connection.

Step 2 - Send it again#

we send the same request a second time on the same connection.

aa

this time our POST / request arrives to find the smuggled G sitting in front of it, so the back end reads the combined request line as GPOST /, treats GPOST as the method, and rejects it as an unknown method. seeing that GPOST error is the lab solved, it shows our smuggled character was prepended to the next request exactly as intended.

with this, we solved the lab!