Request smuggling happens when two HTTP servers in a chain disagree about where one request ends and the next begins. An attacker hides a second request inside the first, and the backend treats it as separate. The defense is strict, matching parsing at every hop, plus keeping software current.
The core idea
A front proxy and a backend share one long connection and send many requests over it. Each must decide the length of every message body. If the proxy thinks the body ends at one point and the backend thinks it ends earlier, the leftover bytes are read by the backend as the start of the next request. That leftover is chosen by the attacker.
RFC 9112 describes smuggling as exploiting differences in protocol parsing among various recipients to hide extra requests inside an apparently harmless one.
Where the disagreement comes from
HTTP/1.1 has two ways to give a body length: a Content-Length header, and chunked Transfer-Encoding. When both appear, parsers historically differed.
RFC 9112 is clear. When a message has both, Transfer-Encoding overrides Content-Length, and the combination might indicate an attempt at request smuggling and ought to be handled as an error. An intermediary that forwards such a message must first remove the received Content-Length field. A sender must not send Content-Length in any message with Transfer-Encoding. A server may reject a request with both, and whether it rejects or not, it must close the connection after responding.
The RFC also warns that lenient request line parsing can lead to smuggling when there are multiple recipients with different interpretations.
What an attacker gains
- Bypass of controls that live at the front, such as access rules or a WAF, because the smuggled request never passes inspection as its own request.
- Poisoned responses for other users sharing the connection.
- Access to paths the proxy was meant to block.
The effects depend on the specific chain, so there is no single fix in config.
What you can do
- Keep every hop patched. Smuggling bugs are usually parser bugs, fixed in releases. Track both the proxy and the backend.
- Prefer HTTP/2 or HTTP/3 end to end where you can. Their framing does not use the same ambiguous length rules, though downgrading at the proxy to HTTP/1.1 can reintroduce risk.
- Reject malformed requests rather than repairing them. Strict parsing is the safer default. Do not turn on options that tolerate invalid headers.
- Do not forward requests that carry both headers. If a hop cannot guarantee correct handling, close the connection.
- Avoid mixing unlike servers without testing. A chain of products with different leniency is where disagreement lives.
- Test with a scanner or review. Dynamic scans can probe for known desync patterns.
nginx keeps some safety defaults here. ignore_invalid_headers is on by default, so headers with invalid names are ignored, and underscores_in_headers is off. Do not weaken them without a reason. Read the nginx timeouts post in this series for related connection settings.
Try it yourself
Open the demo and run the scan against the sample app. Look at how findings are grouped and which ones describe request handling.
Click through it at your own pace, or open it full screen.
Where Safeguard fits
Safeguard cannot patch your proxy, but it tracks the open source components you depend on, and zero-day discovery plus reachability analysis help decide what to fix first. The free scan is at https://gold.safeguard.sh/scan.
Quick check
What does RFC 9112 say when a request has both Content-Length and Transfer-Encoding?
Transfer-Encoding overrides Content-Length, the message may indicate smuggling and ought to be treated as an error, and a forwarding intermediary must remove Content-Length first.
Sources
Last reviewed: 19 October 2026.