Safeguard
Application Security•

ASVS 5.0 V4.2.1: Prevent HTTP Request Smuggling

Every proxy and server in the chain must agree on where an HTTP message ends. Learn the Transfer-Encoding and Content-Length rules and how to test them.

Safeguard Security Team
3 min read

ASVS 5.0 V4.2.1 (level 2) requires every component that handles your traffic, load balancers, firewalls and application servers, to work out where an HTTP message ends using the right rule for the HTTP version. In HTTP/1.x, if Transfer-Encoding is present, Content-Length must be ignored. In HTTP/2 and HTTP/3, a Content-Length header, if present, must match the length of the DATA frames.

The goal is to stop request smuggling, where the front end and back end disagree about message boundaries.

Why it matters

If a proxy thinks a request ends at byte 100 and the backend thinks it ends at byte 60, the leftover 40 bytes become the start of the next request on that shared connection. An attacker uses that to poison another user's request, bypass front end access controls or steal responses. See CWE-444.

The danger is the mix of components. Each one may be fine alone. The bug lives in the disagreement, often when HTTP/2 at the edge is downgraded to HTTP/1.1 behind it.

How to implement it

Most of the fix is configuration and keeping software current.

  • Use maintained versions of your proxy, CDN and application server. Many smuggling bugs were fixed in parsers years ago.
  • Prefer HTTP/2 or HTTP/3 end to end. If the edge downgrades to HTTP/1.1, make sure it rebuilds the message instead of passing raw headers.
  • Reject ambiguous requests at the edge, such as ones with both Transfer-Encoding and Content-Length, duplicate Content-Length values, or obfuscated header names.
  • Disable connection reuse between proxy and backend if you cannot trust the backend parser.

A typical hardening on a Node server:

const server = http.createServer({ insecureHTTPParser: false }, app);
server.headersTimeout = 15000;

Keep insecureHTTPParser off, since turning it on relaxes the rules that block malformed framing.

How to test it

Use a scanner built for smuggling, such as the HTTP Request Smuggler extension for Burp Suite, against your real production topology rather than one server alone. Manually, you can send a request with both headers and watch the response.

printf 'POST / HTTP/1.1\r\nHost: example.com\r\nContent-Length: 6\r\nTransfer-Encoding: chunked\r\n\r\n0\r\n\r\nX' | openssl s_client -quiet -connect example.com:443

A safe edge rejects it with a 400 or closes the connection. Test each hop pair separately: CDN to load balancer, load balancer to app.

Common mistakes

  • Testing only the app server and not the full chain.
  • Assuming HTTP/2 at the edge makes you immune while the backend still speaks HTTP/1.1.
  • Running old proxy versions because nothing is visibly broken.
  • Enabling lenient parsing flags to make a strange client work.
  • Keeping long lived shared connections between proxy and backend without validating framing.

Quick check

In HTTP/1.1, what must a server do if a request has both Transfer-Encoding and Content-Length?

Use Transfer-Encoding and ignore Content-Length. Better still, reject the ambiguous request at the edge.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.