HTTP/1.1’s Limitations - and How F5 Has You Covered
Summary
In his latest research, HTTP/1.1 Must Die, James Kettle of PortSwigger demonstrates how small parsing discrepancies between front-end and back-end servers can create “desync” vulnerabilities - flaws capable of hijacking user sessions, poisoning caches, and in some cases, taking over millions of websites simultaneously.
F5’s WAFs address this evolving threat landscape with deep protocol enforcement, intelligent normalization, targeted attack signatures, and active detection strategies designed to counter even the most advanced desync techniques.
The Fatal Flaw in HTTP/1.1
At its core, HTTP/1.1 has a significant design weakness: it relies on loose, text-based request boundaries with multiple methods for declaring message length (Content-Length and Transfer-Encoding headers).
This ambiguity becomes a playground for attackers, especially when reverse proxies reuse upstream connections between different users. A single parsing discrepancy between front-end and back-end servers can let a malicious request “smuggle” hidden data into another user’s session, enabling cache poisoning, credential theft, or full site takeover.
The Best Solution - Upstream HTTP/2
F5 AWAF supports upstream HTTP/2, which is one of the most effective ways to prevent many HTTP/1.1 desync issues. HTTP/2’s binary framing layer uses explicit message boundaries, which removes conflicting length declarations to abuse. Whenever possible, this should be the first choice. If you choose to stick with HTTP/1.1, the protections outlined below ensure F5 still keeps you safe, even against advanced and emerging attack techniques.
Classic Request Smuggling – CL.TE, TE.CL
The earliest HTTP Request Smuggling techniques exploited mismatches in how front-end and back-end servers interpret CL and TE headers:
- CL.TE - Proxy uses Content-Length; server uses Transfer-Encoding.
- TE.CL - Proxy uses Transfer-Encoding; server uses Content-Length.
These discrepancies stem from incorrect or inconsistent implementation of the HTTP/1.1 specification. According to the RFC, if both Content-Length and Transfer-Encoding headers are present, Transfer-Encoding should take precedence. Proxies or servers that fail to implement this correctly can misinterpret request boundaries. This allows attackers to smuggle hidden requests that are processed in another user’s session.
In both cases, the disagreement on where a request “ends” lets attackers slip in a hidden request, contaminating the next user’s connection. These are well-documented and often mitigated, but still surface in legacy or misconfigured systems.
How F5 Protects You
F5 WAFs enforce strict header consistency and reject any request where CL and TE conflict. They normalize obfuscated values, block malformed headers, and enforce compliance before traffic ever reaches the app.
Any request that includes both Content-Length and Transfer-Encoding headers is treated as an HTTP protocol violation (specifically identified as "Chunked request with Content-Length header" ) and gets blocked.
Also, obfuscating Transfer-Encoding header by adding a trailing space before the colon is blocked by the Trailing Space in Header Name attack signature (ID 200018080).
Figure 1: Request smuggling attempt
Advanced & Emerging Desync Variants
Presented at BlackHat 2025 in the HTTP/1.1 Must Die research, these new techniques push beyond the well-known CL.TE and TE.CL parser discrepancies.
CL.0 Desync via Standard Expect Header
The Expect header is harmless by itself: however, it may lead to other attacks by causing unexpected behaviors in servers and proxies. For example, reading the body of a HEAD request, which traditionally doesn't include an HTTP body block.
Figure 2: Expect-desync attempt using body in HEAD request
The goal of this attack is typically Response Queue Poisoning. By sending a large volume of carefully shaped requests, the attacker attempts to mismatch incoming requests with queued responses and get responses that belong to other users.
Figure 3: Request smuggling with Expect header, blocked by AWAF
How F5 Advanced WAF Blocks the Attack
Figure 4: HTTP violation when adding body to GET or HEAD requests
F5 Advanced WAF identifies cases where a HEAD or GET request includes an unexpected message body (a protocol violation that can indicate exploitation attempts) and blocks these. It also detects when the body of a POST request contains a Host header and blocks it.
Obfuscated Expect-Based CL.0 Desync (CVE-2025-32094)
Obfuscating the Expect header exposed more CL.0 desynchronization vulnerability, as shown in the article.
Figure 5: Advanced Expect-Based CL.0 DesyncAdvanced WAF successfully blocks the request due to the following violations:
- Using the OPTIONS HTTP method: often used in information leakage
- HTTP protocol compliance failure: detection of the newline character in the Expect header
- HTTP Header Injection attack signature (ID 200018023).
This signature detects a suspicious Host header embedded in the request body.
Key Takeaways
From classic CL.TE smuggling to cutting-edge CL.0 desync attacks, the risk is real and evolving.
F5 WAFs address this head-on with:
- Deep protocol compliance enforcement
- Intelligent header normalization
- Obfuscation detection
- Preemptive blocking of suspicious patterns
- Upstream HTTP/2 support, which eliminates entire classes of HTTP/1.1 smuggling vulnerabilities by ensuring a single, unambiguous request framing between proxy and backend
2 Comments
The is a cool article !
The previous one were by AaronJB
HTTP Request Smuggling, what it is, how to find it and how to stop itGreat article! I have read this research in my holiday and planed to write something about it on DevCentral, but you were faster.
As I understand the research:
- The only real solution is to use only HTTP/2 on server side, everything else is patchwork.
- HTTP/1 on client side is not so dangerous.
- OneConnect should be disabled.
I am curious to know who uses http/2 only on serverside in production setups? Most F5 deployments I see don't use HTTP/2 at all.
Edit: What is the best way to enforce HTTP/2 server side connections only?