the_open_door
coffee
ESEN
← Back to index

HTTP Request Smuggling

HTTP Request Smuggling abuses the fact that two chained servers (a front-end or proxy and the back-end) disagree on where one request ends. Once they desync, part of our request "smuggles" onto the front of another user's next request, which lets us bypass front-end controls, poison responses or hijack other people's sessions.

The disagreement comes from two headers that state the body length: Content-Length (CL) and Transfer-Encoding: chunked (TE). When a request carries both and each server prefers a different one, the desync appears. The three classic variants:

CL.TE (front-end uses Content-Length, back-end uses Transfer-Encoding):

POST / HTTP/1.1
Host: victim
Content-Length: 6
Transfer-Encoding: chunked

0

G

The back-end treats 0 as the end of the chunk and leaves G in the buffer, which sticks to the start of the next request (GET).

TE.CL (the other way around): a chunked body whose tail is orphaned for the front-end.

POST / HTTP/1.1
Host: victim
Content-Length: 4
Transfer-Encoding: chunked

5c
GPOST /admin HTTP/1.1
Host: victim

0

TE.TE: both support Transfer-Encoding, but one can be obfuscated so only one honours it (Transfer-Encoding: xchunked, Transfer-Encoding:\tchunked, a duplicate header, etc.).

How to detect it. The most reliable signature is timing: a malformed CL.TE/TE.CL probe leaves the back-end waiting for the rest of the body, so that request (or the next one) takes several extra seconds. On the server side the tells are mismatched responses (one client gets another's response), spikes of 408 Request Timeout, and requests carrying both Content-Length and Transfer-Encoding, which a healthy proxy should reject. Burp (the HTTP Request Smuggler extension) automates the timing probe.

Defence. Normalize the request at the front-end and reject any that carry both CL and TE or an ambiguous TE; use end-to-end HTTP/2 (its length is explicit and removes the ambiguity); and make the same software/version parse the framing across the whole chain. Chains with cache poisoning and, via request stealing, with session hijacking.