HTTP Request Smuggling — A Practical Field Guide
Request smuggling exploits a disagreement between two servers in a chain about where one request ends and the next begins. When a front-end proxy and a back-end origin parse the same bytes differently, an attacker can prepend a hidden request onto someone else's connection — poisoning responses, capturing other users' traffic, and bypassing front-end controls entirely.
It is one of the few remaining bug classes where a single request can compromise other users without touching their session directly. Here's how we work it.
The core disagreement
HTTP/1.1 offers two ways to state a body's length: Content-Length and Transfer-Encoding: chunked. The spec says if both are present, use Transfer-Encoding. Real deployments don't always agree. The classic families:
- CL.TE — front-end honors
Content-Length, back-end honorsTransfer-Encoding. - TE.CL — the reverse.
- TE.TE — both support chunked, but one can be tricked into ignoring it via an obfuscated header (
Transfer-Encoding: xchunked, a space before the colon, a duplicated header, a tab).
The smuggled bytes that the front-end counts as "body" get re-interpreted by the back-end as the start of the next request.
Detect with timing, confirm with state
Never confirm smuggling by breaking a shared connection on production — you can wedge the queue for real users. Detect safely:
- Timing probe. Send a request crafted so that if the back-end waits for bytes that never come, it hangs. A CL.TE probe with an incomplete chunked body makes a vulnerable back-end stall for the timeout; a patched one responds immediately. A multi-second delta is your signal, and it disturbs nothing.
- Confirm on yourself. Smuggle a prefix that affects your own next request — e.g., route your follow-up to a different, harmless endpoint, or prepend a header you can observe in your own response. You prove the parser split without ever capturing a stranger.
Only escalate to impact you can demonstrate against your own traffic.
The modern variants matter more than CL/TE
The classic CL/TE bugs are largely patched at mature front-ends. The findings that still land in 2026:
- H2.CL / H2.TE downgrade smuggling. The front-end speaks HTTP/2 to the client but downgrades to HTTP/1.1 to the origin. If it rebuilds the
Content-Lengthnaively from an HTTP/2 body, you smuggle across the downgrade. HTTP/2's explicit framing was supposed to end this — sloppy downgrades reopened it. - CL.0 and "H2.0". The back-end ignores the body entirely on certain paths (static handlers, redirects), treating
Content-Lengthas0, so your "body" becomes a full second request. Hunt these on endpoints that respond before reading the body. - Header injection via CRLF in HTTP/2 — pseudo-header and value smuggling that becomes request splitting after downgrade.
What it's actually worth
Impact, roughly ascending:
- Bypass front-end access control — reach an internal path the proxy was supposed to block, because the back-end sees a request the front-end never inspected.
- Cache poisoning — pair the split with an unkeyed input to serve your response to every subsequent visitor of a page.
- Capture other users' requests — smuggle a prefix that causes the victim's next request to be appended to a request that stores and reflects it. This is the crown-jewel outcome: harvesting session tokens and PII from live traffic.
For a report, (1) and (2) are provable against your own traffic and a benign marker. (3) you demonstrate structurally — show the storage endpoint, the split, and that a subsequent request lands appended — without ever collecting a real user's data.
Discipline
Smuggling touches shared infrastructure. Rate-limit yourself, prefer timing detection, never run a capture that would ingest third-party requests on production, and coordinate a test window when the program allows. The technique is powerful precisely because it reaches other people — which is exactly why you handle it with more care than any other class.