HTTP request smuggling occurs when two systems on one connection disagree about where one request ends and the next begins. A load balancer or reverse proxy reads the message differently from the backend server. Bytes treated as part of the first request by the frontend may become a smuggled second request at the backend, or vice versa.
How does request smuggling arise?
HTTP/1.1 can delimit a body using Content-Length or Transfer-Encoding: chunked. Ambiguous, duplicate or unusually formatted headers encounter a chain of CDN, WAF, proxy, gateway and application server. When components use different rules, parsers or normalization, part of the attacker's request remains on a reused backend connection and is combined with the next legitimate request.
The vulnerability therefore exists in the combination of systems. One server may appear to process the request correctly while the dangerous difference arises only at the next component.
What do CL.TE, TE.CL and TE.TE mean?
| Variant | Difference |
|---|---|
| CL.TE | Frontend delimits by Content-Length, backend by Transfer-Encoding. |
| TE.CL | Frontend uses Transfer-Encoding, backend Content-Length. |
| TE.TE | Both support Transfer-Encoding, but one fails to recognize an obfuscated or unusually formatted header. |
| CL.0 / client-side desync | A component expects no bytes despite a stated body, or browser and server lose connection synchronization. |
These names describe parser decisions, not complete exploits. Modern variants use duplicate headers, invalid chunk sizes, whitespace, line endings and other differences. Blocking a list of historical payloads is not durable protection.
What role do HTTP/2 and HTTP/3 play?
HTTP/2 uses binary frames and does not have the same ambiguity as HTTP/1 text syntax. Many frontends translate requests for an HTTP/1.1 backend. If downgrade creates a contradictory length, unchecked header or malformed new request line, desynchronization returns at the protocol boundary. HTTP/2-specific variants are often called H2.CL or H2.TE. HTTP/3 does not automatically remove risk when gateways translate into vulnerable downstream protocols.
Which attacks become possible?
- Bypass security controls: The frontend checks a harmless outer request while the backend processes the smuggled one.
- Influence requests: A prefix or body is attached to the next user's request or directs it toward an attacker endpoint.
- Swap responses: A user receives a response belonging to another request, potentially exposing data.
- Cache poisoning: A smuggled response is stored under a public cache key.
- Reach internal functions: Routing, host or path checks on upstream systems are bypassed.
Impact is often unstable and affects random other connections. This makes the vulnerability both critical and difficult to reproduce.
How is request smuggling prevented?
- Reject ambiguity: Return an error for contradictory, duplicate or invalid length and transfer headers and close the connection.
- Use consistent protocols: Prefer HTTP/2 end-to-end or normalize downgrade strictly and unambiguously.
- Use one parse result: Parse completely at the frontend and create a clean downstream request instead of forwarding problematic raw bytes.
- Keep components current: Inventory and patch CDN, WAF, proxy, gateway, server and framework together.
- Protect backends: Accept connections only from trusted frontends and block unexpected direct access.
- Limit connection reuse: Do not try to continue a connection after parser errors or uncertain delimitation.
Protocol example: a request with conflicting framing
POST /example HTTP/1.1
Host: application.example
Content-Length: 6
Transfer-Encoding: chunked
0
X
The frontend and backend must not prioritise different headers. The safe response is to reject the request as invalid, close the connection and avoid forwarding partially parsed bytes.
if hasHeader('Content-Length') and hasHeader('Transfer-Encoding'):
reject(400)
closeConnection()
request = parseCompletelyWithOneStrictParser()
forward(serializeFreshRequest(request))
This pseudocode expresses an architectural rule, not a standalone patch. Every real component in the chain must accept the same valid messages and reject the same ambiguous ones.
How is it tested and detected safely?
Production testing is sensitive because a crafted request can affect the next real user's request. Authorized testers begin with timing or differential methods on controlled endpoints and their own connections. Destructive cache or victim proofs require explicit approval. Monitoring looks for rejected ambiguous requests, unusual 400 responses, backend requests lacking a matching frontend ID, response mismatches and connection errors. Frontend and backend logs need a shared request ID for correlation.
Thank you for your feedback! We will review it and optimize this content.
Do you have feedback on HTTP Request Smuggling? Tell us!
Additional Services
Comprehensive IT security solutions for complete protection
Red Teaming
Simulation of real attacks on your company including people, infrastructure and processes. A comprehensive approach to testing your entire security strategy.
Learn morePhishing Exercises
Practical phishing simulations to raise employee awareness. Increase awareness and reduce the risk of successful email-based attacks.
Learn more