← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

HTTP Desync Attack

Security CWE-444 OWASP A5:2021 CVSS 9.0 Advanced
debt(d7/e5/b5/t9)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). Detection requires specialized tools like Burp Suite's http-request-smuggler or smuggler.py actively probing the live proxy chain; no linter or SAST on a single codebase can see it since the flaw exists between components.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). Quick_fix requires coordinated changes across edge proxy config (reject dual CL+TE, normalize chunked) and upstream framing agreement, plus potentially reworking HTTP/2 termination to be end-to-end - spans multiple infrastructure components.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Applies to all web/api contexts fronted by proxies; every proxy upgrade, CDN swap, or topology change requires re-validation of framing agreement across hops, imposing ongoing architectural vigilance.

t9 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'catastrophic trap' (t9). The misconception is explicit: developers assume malformed bodies are required and that WAF/CDN inspection protects the origin, but valid well-formed requests smuggle straight past all edge defenses - the intuitive mental model is exactly inverted from reality.

About DEBT scoring →

Also Known As

request queue poisoning CL.TE attack TE.CL attack HTTP/2 downgrade smuggling

TL;DR

Exploiting disagreement between front-end proxy and back-end server about where one HTTP request ends and the next begins.

Explanation

HTTP desync attacks (also called request queue poisoning) exploit the fact that HTTP connections between reverse proxies, CDNs, load balancers, and origin servers are typically reused across many requests. If the front-end proxy and the back-end server disagree about the length of a request - for example because one honours Content-Length while the other honours Transfer-Encoding: chunked - an attacker can smuggle a partial request that gets prepended to the next legitimate user's request on that shared connection. The victim then unknowingly executes attacker-controlled headers or a completely different URL, enabling cache poisoning, credential theft, bypass of front-end security controls, and hijacking of authenticated sessions.

While often grouped with HTTP request smuggling, desync attacks focus specifically on the state disagreement between intermediaries rather than on malformed bodies. Classic variants include CL.TE (front-end uses Content-Length, back-end uses Transfer-Encoding), TE.CL (the reverse), and TE.TE (both use Transfer-Encoding but one is tricked into ignoring it via header obfuscation). Newer variants exploit HTTP/2-to-HTTP/1.1 downgrades where H2 pseudo-headers or trailing whitespace are translated into ambiguous H1 requests. Browser-powered variants (client-side desync) even let a malicious webpage poison the victim's own connection to a target.

Mitigation requires that every hop in the request chain parse HTTP identically and strictly. Prefer HTTP/2 end-to-end without downgrade to HTTP/1.1. If downgrade is unavoidable, normalise or reject ambiguous requests at the front-end: strip or reject requests with both Content-Length and Transfer-Encoding, reject Transfer-Encoding values other than exactly 'chunked', and reject headers with leading whitespace or malformed line folding. Disable connection reuse between proxy and origin as defence-in-depth. Regularly test with tools like HTTP Request Smuggler (Burp) since new variants continue to be discovered.

Diagram

sequenceDiagram
    participant A as Attacker
    participant P as Front Proxy (CL)
    participant O as Origin (TE)
    participant V as Victim
    A->>P: POST / with CL:6 + TE:chunked (smuggled GET /admin)
    P->>O: Forwards whole body (CL=6)
    Note over O: Reads chunked, stops early<br/>Leftover bytes stay in queue
    V->>P: GET /home (Cookie: session=victim)
    P->>O: Forwards on same reused connection
    Note over O: Prepends leftover: GET /admin + victim cookies
    O-->>V: Admin page response

Common Misconception

Desync attacks require malformed or exotic request bodies. In reality, the request bodies are valid HTTP - the vulnerability lies in two intermediaries interpreting the same well-formed headers differently, causing them to lose sync about request boundaries on a reused connection.

Why It Matters

A single desync primitive can hijack any user's session on the target, bypass every front-end WAF and authentication check, and poison shared caches to compromise thousands of users at once. Because the flaw lives between components rather than in either alone, code audits of a single service will not find it.

Common Mistakes

  • Assuming a WAF or CDN at the edge protects the origin - desync smuggles requests past the front-end entirely so its inspection never applies.
  • Only defending against malformed bodies while allowing both Content-Length and Transfer-Encoding headers on the same request.
  • Terminating HTTP/2 at the CDN and downgrading to HTTP/1.1 to the origin without validating header content, enabling H2.CL and H2.TE attacks.
  • Enabling keep-alive between proxy and origin without ensuring both agree on request framing, giving smuggled requests a shared queue to poison.
  • Testing only for classic CL.TE/TE.CL variants and ignoring newer browser-based client-side desync and HTTP/2 downgrade issues.

Avoid When

  • Do not attempt fixes only in application code - desync lives in the proxy/origin boundary and must be fixed at the HTTP-parsing layer of every hop.
  • Do not rely solely on WAF rules to block smuggling payloads; the whole point of desync is to smuggle past the front-end where the WAF sits.

When To Use

  • Whenever a system fronts an origin server with a reverse proxy, CDN, or load balancer - especially when HTTP/2 is terminated at the edge and downgraded to HTTP/1.1 upstream.
  • During architecture reviews of any multi-hop HTTP topology with connection reuse, and after upgrading or replacing any proxy or web server component in the chain.

Code Examples

✗ Vulnerable
# nginx forwarding to a backend that also runs HTTP/1.1 with keep-alive,
# but with no normalisation of ambiguous framing headers.

upstream app { server 10.0.0.5:8080; keepalive 64; }

server {
    listen 443 ssl http2;
    location / {
        proxy_pass http://app;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        # No filtering: requests carrying BOTH Content-Length
        # AND Transfer-Encoding are forwarded verbatim.
        # nginx uses CL, backend (e.g. old gunicorn) uses TE -> desync.
    }
}
✓ Fixed
# 1. Reject ambiguous framing at the edge before it reaches the origin.

server {
    listen 443 ssl http2;

    # Reject any request that supplies both framing mechanisms.
    if ($http_transfer_encoding != "") {
        if ($http_content_length != "") { return 400; }
    }
    # Reject non-standard Transfer-Encoding values (obfuscation vectors).
    if ($http_transfer_encoding !~* "^(chunked)?$") { return 400; }

    location / {
        proxy_pass http://app;
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # Defence in depth: disable upstream keep-alive so a smuggled
        # request cannot poison a following user's request.
        # (Remove `keepalive` from the upstream block.)
    }
}

# 2. Prefer end-to-end HTTP/2 to the origin to eliminate the H1 framing
#    ambiguity altogether (nginx: `grpc_pass` or an H2-capable proxy).

Added 9 Sep 2026
Views 26
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 3 pings W 2 pings T 1 ping F 0 pings S 0 pings S 2 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Google 4 Perplexity 2 SEMrush 2 Ahrefs 1 Unknown AI 1
crawler 10
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: High
⚡ Quick Fix
Reject any request that carries both Content-Length and Transfer-Encoding, normalise chunked encoding at the edge, and prefer HTTP/2 end-to-end without downgrade to HTTP/1.1.
📦 Applies To
web api nginx haproxy cloudflare aws-alb apache
🔗 Prerequisites
🔍 Detection Hints
(?i)proxy_http_version\s+1\.1|keepalive\s+\d+|http_transfer_encoding|(Transfer-Encoding:\s*chunked.*Content-Length:|Content-Length:.*Transfer-Encoding:\s*chunked)
Auto-detectable: ✓ Yes burpsuite http-request-smuggler smuggler.py
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Low ✗ Manual fix Fix: High Context: File Tests: Regenerate
CWE-444 CWE-436


✓ schema.org compliant