Wiki: HTTP Request Smuggling
TL;DR
- Request smuggling happens when frontend and backend parse
Content-LengthandTransfer-Encodingdifferently. - Classic case: frontend uses CL, backend uses TE (CL.TE).
- Look for desync: one request becomes two for the backend.
Concept
If the frontend trusts Content-Length and the backend trusts Transfer-Encoding: chunked, you can end the chunked body early and smuggle a second request in the remaining bytes.
Minimal CL.TE Example
POST / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Transfer-Encoding: chunked
0
GET /404 HTTP/1.1
X-Ignore: X
Why it works
- Frontend: reads 35 bytes of body and forwards them as one request.
- Backend: sees
0\r\n\r\nand ends the request early, then treatsGET /404as a new request.
What to Look For
- Responses mismatching your visible request (e.g., you request
/but get/404). - Desync only shows up on keep-alive connections.
- Behavior depends on the proxy chain (nginx, HAProxy, load balancer).
Safe Testing Notes
- Test in-scope only; be careful with payload counts.
- Watch for unstable behavior or queue poisoning.
- Use tooling that controls connection reuse and pipelining.