HTTP Request Smuggling has been around since 2005. In 2026, it's still silently bypassing WAFs, hijacking sessions, and exposing back-end infrastructure — because most stacks still haven't fully moved on from HTTP/1.1.

What Is HTTP Request Smuggling?

At its core, HTTP request smuggling exploits a disagreement between two servers about where one HTTP request ends and the next begins.

HTTP/1.1 provides two ways to define the length of a request body:

  • Content-Length — declares the exact byte count of the body
  • Transfer-Encoding: chunked — splits the body into chunks, with a zero-length chunk signalling the end

When a front-end proxy and a back-end server handle these headers differently, an attacker can craft a request that each server interprets in a completely different way. The attacker effectively smuggles a hidden second request inside the first — one that the front-end never sees, but the back-end processes.

The Three Attack Variants

CL.TE — Front-end trusts Content-Length, back-end uses Transfer-Encoding

The front-end reads the full request using Content-Length and forwards it. The back-end processes it as chunked — and interprets the remainder as the start of a new, attacker-controlled request.

POST / HTTP/1.1
Host: vulnerable-site.com
Content-Length: 30
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
X-Ignore: x

The front-end sees one request. The back-end sees two.

TE.CL — Front-end uses Transfer-Encoding, back-end trusts Content-Length

The front-end processes the chunked body and forwards it. The back-end, reading by Content-Length, consumes fewer bytes — leaving the rest to be prepended to the next incoming request.

TE.TE — Both servers support Transfer-Encoding, but one can be confused

The attacker obfuscates the Transfer-Encoding header so one server processes it while the other ignores it and falls back to Content-Length:

Transfer-Encoding: chunked
Transfer-Encoding: identity
Transfer-Encoding:\x0bchunked

One parser accepts it. The other rejects it. Desync achieved.

What an Attacker Can Actually Do

Bypass WAFs and Front-End Security Controls

Every WAF rule, IP allowlist, and access control you've configured lives on the front-end proxy. The back-end trusts whatever the proxy forwards. Smuggle a request directly to the back-end and you've skipped the entire security layer.

GET /internal/admin/users HTTP/1.1
Host: internal-app

Steal Other Users' Requests

By poisoning the server's request queue, an attacker can cause a victim's full HTTP request to be appended to a request the attacker controls. That means session cookies, authorization tokens, and POST body data get reflected back to the attacker.

This is particularly devastating in shared hosting or high-traffic environments where many users hit the same back-end connection pool.

Cache Poisoning

Smuggle a request that causes the proxy to cache a malicious response — then serve it to every user who requests that resource. XSS payloads, redirects, credential harvesting pages: all deliverable at scale.

Response Queue Desync (HTTP/2 Downgrade)

When a front-end speaks HTTP/2 to clients but downgrades to HTTP/1.1 toward the back-end, the framing mismatch opens an entirely new class of desync attacks. Attacker-controlled responses can be delivered to arbitrary users — enabling account takeover without any interaction beyond a single smuggled request.

How to Detect It

Burp Suite + HTTP Request Smuggler extension is the standard. It automates CL.TE, TE.CL, and TE.TE probing and surfaces timing anomalies that indicate a vulnerable pipeline.

For manual timing-based detection on a CL.TE target:

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

1
A
X

If the server hangs for 10+ seconds before responding, it's waiting for the rest of a chunk that the front-end already considered complete. You've found a desync.

Other indicators in logs and monitoring:

  • Intermittent 400/500 errors on otherwise valid requests
  • Session crossover — users seeing responses intended for others
  • Requests arriving at the back-end with unexpected prefixes

How to Fix It

1. Upgrade to HTTP/2 end-to-end. HTTP/2 uses a binary framing layer with explicit stream IDs. There is no Content-Length vs Transfer-Encoding ambiguity. This is the most effective long-term fix.

2. Reject ambiguous requests at the edge. Configure your front-end proxy to drop any request that contains both Content-Length and Transfer-Encoding. Most modern proxies support this.

# Nginx — reject conflicting length headers
if ($http_transfer_encoding ~* "chunked") {
    return 400;
}

3. Disable HTTP/1.1 keep-alive on internal connections. Force each request onto its own connection between proxy and back-end. This eliminates the pipeline entirely — no shared connection, no desync.

4. Normalize before forwarding. Strip or rewrite Transfer-Encoding headers at the front-end so the back-end only ever sees Content-Length. Many WAF and proxy configurations support this natively.

5. Run regular smuggling scans. Add Burp's HTTP Request Smuggler to your standard pentest checklist. It takes minutes to run and consistently finds real vulnerabilities across modern infrastructure.

References

PortSwigger Web Security — HTTP Request Smuggling: https://portswigger.net/web-security/request-smuggling

James Kettle — HTTP Desync Attacks: Request Smuggling Reborn (DEF CON 27, 2019): https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn

RFC 7230 — HTTP/1.1: Message Syntax and Routing (IETF): https://datatracker.ietf.org/doc/html/rfc7230

OWASP Testing Guide — WSTG-INPV-15: Testing for HTTP Splitting/Smuggling: https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/15-Testing_for_HTTP_Splitting_Smuggling

Amit Klein — Divide and Conquer: HTTP Response Splitting, Web Cache Poisoning Attacks (2004): https://packetstormsecurity.com/papers/general/whitepaper_httpresponse.pdf