HTTP Request Smuggling

The Content-Length vs Transfer-Encoding ambiguity, CL.TE/TE.CL/TE.TE variants, front-end/back-end desync, impact, and defenses (normalize, end-to-end HTTP/2, reject ambiguous).

HTTP request smuggling is an attack that makes two servers disagree about where a request ends on the same TCP connection, letting an attacker slip part of their request onto the front of the next user's request. Today's web often puts a front-end (CDN, reverse proxy) in front, forwarding requests to a back-end server over a shared connection — and when the two disagree about where a request ends, that gap opens.

Content-Length vs Transfer-Encoding

There are two ways to state a request body's length. Content-Length gives the byte count as a number, while Transfer-Encoding: chunked splits the body into chunks, each prefixed by its size in hex and terminated by a zero-size chunk. The trouble comes when both headers appear on one request. The standard (RFC 9112) says to prefer Transfer-Encoding and ignore Content-Length, but not every real-world server does the same. When the front-end trusts Content-Length while the back-end trusts Transfer-Encodingtheir interpretations diverge — and the request boundary slips.

CL.TE / TE.CL / TE.TE

This parsing mismatch splits into three classic variants depending on which server uses which header.

POST / HTTP/1.1
Host: victim.example
Content-Length: 13
Transfer-Encoding: chunked

0

GPOST / HTTP/1.1
Host: victim.example
...

In this CL.TE example the front-end reads Content-Length: 13 and forwards everything up to 0\r\n\r\nGPOST... as one request to the back-end. But the back-end follows Transfer-Encoding: chunked, sees the request end at the 0 chunk, and treats the leftover GPOST / HTTP/1.1 ... as the beginning of the next request. That leftover fragment is the 'smuggled' request.

Front-end / back-end desync

That leftover fragment sits in the back-end's connection buffer and prepends itself to the next legitimate user's request that arrives on the same connection. The victim's request is then processed mixed with the path and headers the attacker planted (request desync). Because the front-end and back-end have lost their 'agreement' about the request stream, the divergence can cascade for as long as the connection stays alive.

Impact

The impact is severe. An attacker can bypass front-end access control (WAF, auth) to reach forbidden back-end paths, hijack another user's request to steal sessions or credentials, scramble responses so a victim sees the wrong page (response queue poisoning), or poison a cache to spread malicious content widely. A single parsing mismatch can collapse several defenses — authentication, isolation, and caching — at once.

Defenses