HTTP Request Smuggling
Exploit disagreements between front-end and back-end servers about where one HTTP request ends and the next begins — and understand why it's a favorite WAF-bypass technique.
Learning Objectives
- → Explain why HTTP request smuggling exists: front-end/back-end disagreement on request boundaries
- → Distinguish CL.TE, TE.CL, and TE.TE smuggling variants
- → Explain how a smuggled request can poison another user's request queue
- → Identify defenses that eliminate request smuggling at the architecture level
- → Explain why request smuggling is a common technique for bypassing WAFs
Why Request Smuggling Exists
Most modern web architectures chain multiple HTTP servers together: a CDN, a load balancer, a WAF, and finally the origin application server. Each of these parses HTTP requests independently. Request smuggling exploits a disagreement between two servers in that chain about exactly where one HTTP request ends and the next begins — when they disagree, an attacker can smuggle a second, hidden request that the back-end processes as if it came from someone else entirely.
The Root Cause: Two Ways to Specify Length
HTTP/1.1 gives two different headers for telling a server how long a request body is:
- Content-Length — an exact byte count
- Transfer-Encoding: chunked — the body is sent in chunks, each prefixed with its own length, ending with a zero-length chunk
If a request somehow includes both headers, or a malformed version of one, front-end and back-end servers can disagree about which one to trust — and that disagreement is the entire vulnerability.
The Three Variants
| Variant | Front-end trusts | Back-end trusts | Result |
|---|---|---|---|
| CL.TE | Content-Length | Transfer-Encoding | Front-end forwards a "complete" request; back-end reads less than that, leaving smuggled bytes to be interpreted as the start of the next request |
| TE.CL | Transfer-Encoding | Content-Length | Front-end reads the chunked body fully; back-end reads only Content-Length bytes, again leaving a hidden remainder |
| TE.TE | Transfer-Encoding | Transfer-Encoding | Both use chunked encoding, but one can be tricked into ignoring the header (e.g. via subtly malformed syntax), reverting it to CL.TE or TE.CL behavior |
How a Smuggled Request Poisons the Queue
Because the back-end connection to the origin server is typically reused (kept alive) across multiple front-end-forwarded requests for performance, a successfully smuggled request doesn't just affect the attacker's own connection — it gets prepended onto the next unrelated user's request on that same back-end connection. This is what makes smuggling so dangerous: it can hijack another real user's session, redirect their request, or capture their response.
Detecting Request Smuggling
The classic technique is a timing-based probe: send an ambiguous request and see if the back-end appears to "hang," waiting for bytes that never arrive — a strong signal the back-end interpreted the length differently than the front-end did.
Defenses
| Defense | Why it works |
|---|---|
| Use HTTP/2 end-to-end | HTTP/2's binary framing has no equivalent length ambiguity |
| Reject ambiguous requests | If both Content-Length and Transfer-Encoding are present, or Transfer-Encoding is malformed, reject the request outright rather than guessing |
| Normalize at every hop | Ensure every server in the chain agrees on strict HTTP parsing, ideally via the same library/config |
| Disable connection reuse for untrusted paths | Removes the "poisoned queue" blast radius, at a performance cost |
Why This Is a Common WAF Bypass Technique
A WAF inspects the request it parses — if request smuggling causes the WAF to see a different request boundary than the origin server does, the smuggled portion never gets inspected by the WAF at all, arriving at the origin as if it passed clean. This is exactly why request smuggling and WAF bypass are so often discussed together.
Common Pitfalls
- Assuming HTTPS prevents request smuggling — TLS protects transport confidentiality, not HTTP parsing logic between hops
- Fixing smuggling at only one hop in the chain while other hops still parse ambiguously
- Underestimating the blast radius — a single successful smuggle can affect every subsequent user on a reused connection, not just the attacker
Request smuggling is a parsing disagreement, not an encryption or DNS issue.
What is the fundamental disagreement that makes HTTP request smuggling possible?
Each variant name describes which header the front-end trusts, followed by which header the back-end trusts.
In a CL.TE attack, which header does the FRONT-END server trust to determine request length?
Connection reuse for performance is exactly what turns a local parsing bug into a queue-poisoning attack affecting other users.
Why can a smuggled request affect a completely different, unrelated user?
💪 Exercises & Challenges
HTTP Request Smuggling MCQ
Test your understanding of HTTP Request Smuggling.
Diagnose a CL.TE Smuggling Scenario
A front-end proxy forwards requests based on the Content-Length header. The origin server processes requests based on Transfer-Encoding: chunked. Given a request with both headers set, where the Conte
Identify the Smuggling Variant
A pentest report describes: 'The front-end load balancer honors Content-Length. The origin application server honors Transfer-Encoding when both headers are present. We crafted a request where the dec