3 minute read

HTTP Request Smuggling is a technique that exploits parsing disagreements between front-end and back-end HTTP servers. When two servers in a chain disagree on where one request ends and the next begins, an attacker can “smuggle” a crafted request through the front-end, causing the back-end to interpret part of it as a separate, attacker-controlled request.

This article documents my research into HTTP smuggling across various proxy and server combinations, building on the foundational work by James Kettle at PortSwigger.

Background

The root cause lies in how HTTP/1.1 determines message body length. RFC 7230 Section 3.3.3 defines the precedence:

  1. If a Transfer-Encoding header is present and the value is “chunked”, the message body is chunked-encoded
  2. If a Content-Length header is present, it defines the body length in bytes
  3. If both are present, Transfer-Encoding takes precedence

The problem arises when a front-end proxy and back-end server apply these rules differently.

CL.TE - Content-Length vs Transfer-Encoding

In this variant, the front-end uses Content-Length while the back-end uses Transfer-Encoding:

POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

The front-end reads 13 bytes (the entire body including “0\r\n\r\nSMUGGLED”) and forwards everything to the back-end. The back-end processes chunked encoding, sees chunk size 0 (terminator), and treats everything after the terminator as the beginning of the next request.

TE.CL - Transfer-Encoding vs Content-Length

Here the front-end uses Transfer-Encoding and the back-end uses Content-Length:

POST / HTTP/1.1
Host: target.com
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

The front-end processes the entire chunked body (chunk of size 8, then terminator 0). The back-end reads only 3 bytes based on Content-Length (“8\r\n”), and the remaining “SMUGGLED\r\n0\r\n\r\n” becomes the start of the next request.

TE.TE - Transfer-Encoding Obfuscation

When both servers use Transfer-Encoding, we can still cause a parsing differential by obfuscating the header so one server recognizes it and the other does not:

Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-encoding: chunked

Different servers have different tolerances for whitespace, capitalization, and invalid values. I tested 14 proxy/server combinations and found that the obfuscation technique Transfer-Encoding: chunked with a preceding space is effective against 3 of them even in 2019.

HTTP/1.1 Connection Reuse

For smuggling to work, the front-end must reuse TCP connections to the back-end across multiple client requests. This is the default behavior for most reverse proxies including Nginx, HAProxy, and Apache mod_proxy.

The attack becomes particularly dangerous when the front-end adds security-critical headers (like X-Forwarded-For or authentication tokens) that the smuggled request bypasses.

Testing Methodology

I developed a systematic approach to detect smuggling vulnerabilities:

Step 1: Send a request with both CL and TE headers where CL is slightly too short. If the response times out (the back-end is waiting for more chunked data), CL.TE may be present.

Step 2: Send a request where TE terminator is followed by a partial second request. If the next legitimate request receives an unexpected response, smuggling is confirmed.

Step 3: Document the exact parser differential and build a proof-of-concept that demonstrates request hijacking.

Practical Impact

With a confirmed smuggling primitive, several attacks become possible:

  1. Bypassing front-end security controls - WAF rules, IP restrictions, and authentication can be bypassed since the smuggled request is not evaluated by the front-end
  2. Request hijacking - capturing another user’s request by smuggling a partial request that causes the next user’s request to be appended as a body parameter
  3. Web cache poisoning - poisoning cached responses when a shared cache sits in the path
  4. Credential theft - smuggling a request that redirects to an attacker-controlled server, stealing the victim’s cookies in the Referer header

Lab Environment

I built an HTTP Smuggling Lab environment for researchers to practice these techniques safely. The lab includes multiple proxy/server configurations with known vulnerabilities.

Affected Software

During my research, I found and reported smuggling issues in several implementations. The key finding was that header normalization remains inconsistent across the HTTP ecosystem, and even “correct” implementations can produce insecure behavior when combined.

Mitigation

For defenders:

  • Use HTTP/2 end-to-end between proxy and back-end when possible
  • Configure the front-end to normalize or reject ambiguous requests
  • Ensure CL and TE agreement across all servers in the chain
  • Disable connection reuse to back-ends as a last resort (performance impact)
  • Deploy request smuggling detection at the WAF level

References

  • James Kettle, “HTTP Desync Attacks: Request Smuggling Reborn” (2019)
  • RFC 7230, Section 3.3.3 - Message Body Length
  • Amit Klein, “HTTP Request Smuggling” (2005)
  • Regis Leroy, “HTTP Request Smuggling in 2020”