ofensiva
http request smuggling
request smuggling
http desync

HTTP Request Smuggling: Attacks and Defense

HTTP request smuggling: front-end/back-end desync (CL.TE, TE.CL, TE.TE, HTTP/2 downgrade), Burp detection and normalization defenses.

SecraJuly 6, 202611 min read

HTTP request smuggling is a technique that abuses the fact that two chained servers (a front-end and a back-end) disagree on where an HTTP request ends. When the front proxy and the application server do not agree on the length of the body, an attacker can hide one request inside another, poison the reused connection and affect other users' requests. The outcome ranges from bypassing perimeter controls to hijacking other people's sessions, without exploiting any memory bug: the entire attack lives in the ambiguity of the protocol itself.

This guide covers why front-end/back-end desync happens, the classic variants (CL.TE, TE.CL and TE.TE), modern smuggling over HTTP/2 and downgrade, how it is detected with Burp Suite and which normalization defenses actually close the vector.

The essentials. Request smuggling is not a bug in one specific server, it is a parsing disagreement between two servers that share a TCP connection. The root cause is usually divergent handling of the Content-Length and Transfer-Encoding headers. Effective defenses are to normalize or reject ambiguous requests at the front-end, use end to end HTTP/2 with no downgrade and, as a last resort, disable connection reuse to the back-end.

What HTTP request smuggling is

Almost no modern application serves the user directly. Between the client and the application server sits a chain: load balancers, CDNs, reverse proxies, WAFs and gateways. To stay efficient, those components reuse TCP connections to the back-end: several requests from different users travel over the same connection, one after another.

The problem shows up when the front-end and the back-end delimit requests differently. HTTP/1.1 offers two mechanisms to signal body length:

  • Content-Length: declares the exact number of bytes in the body.
  • Transfer-Encoding: chunked: the body arrives in fragments, each preceded by its size in hexadecimal, ending with a zero-size fragment.

The specification (RFC 9112, formerly RFC 7230) is clear: if a request includes both headers, Content-Length must be ignored or the request rejected. In practice many servers do not follow the rule the same way. If the front-end honors Content-Length and the back-end honors Transfer-Encoding (or the other way around), the attacker controls where each server believes the request ends. That mismatch is the desync, and whatever is left over for one of the servers becomes the prefix of the next request in the queue.

How the front-end/back-end desync happens

Suppose the attacker sends a single request with contradictory headers. The front-end reads it whole according to its own criterion and forwards it over the persistent connection to the back-end. The back-end, applying the other criterion, treats part of those bytes as a new, independent request. Those bytes sit "waiting" at the start of the connection buffer.

When another legitimate user sends their request over that same reused connection, the back-end concatenates it after the smuggled fragment. The attacker has prepended their payload to the victim's request and can redirect it to a different endpoint, capture their session cookie or force a poisoned response, with no credentials required.

Two conditions are required: a chain of at least two servers with divergent parsing, and a connection to the back-end that is reused across requests. That is why the technique is especially relevant in architectures with CDNs, reverse proxies and microservices.

Classic variants: CL.TE, TE.CL and TE.TE

The naming describes which header each server prioritizes. The first token is the front-end, the second is the back-end.

CL.TE

The front-end uses Content-Length and the back-end uses Transfer-Encoding. The attacker declares a Content-Length that covers only the beginning of the body. The front-end forwards everything, but the back-end, processing the chunked encoding, closes the request at the zero-size fragment and treats the rest as a new request. It is the most common variant against front-ends that do not support chunked.

TE.CL

The front-end uses Transfer-Encoding and the back-end uses Content-Length. Here the attacker builds a chunked body that the front-end sees as a complete request, while the back-end, guided by a short Content-Length, cuts earlier and leaves the rest of the chunk as the start of the next request. It requires careful tuning of the hexadecimal sizes.

TE.TE

Both servers support Transfer-Encoding, but one of them can be induced to ignore it through header obfuscation. Variants such as Transfer-Encoding: xchunked, a space before the colon, Transfer-Encoding : chunked, embedded line breaks or a duplicated header make one server process it and the other not. By disabling interpretation on one of the two, TE.TE degenerates into a CL.TE or TE.CL case.

HTTP/2 downgrade and modern desync

HTTP/2 in theory removes the problem because it uses a frame with explicit length instead of ambiguous text headers. The risk returns when the front-end speaks HTTP/2 to the client but translates (downgrades) to HTTP/1.1 toward the back-end. In that rewrite, malicious values embedded in the pseudo-headers or in headers like content-length and transfer-encoding turn into ambiguous HTTP/1.1 requests downstream. James Kettle documented these families in "HTTP/2: The Sequel is Always Worse" (Black Hat 2021), including H2.CL and H2.TE, where the length declared in the HTTP/2 frame does not match what the back-end sees after the downgrade.

In recent years variants have appeared that do not need a classic contradictory length header:

  • CL.0: the back-end fully ignores Content-Length on certain routes (for example static files or redirects), so the body is interpreted as an independent request.
  • Client-side desync (0.CL) and browser-powered request smuggling: techniques presented by Kettle in 2022 that let the desync be triggered from the victim's browser, extending the impact to targets that only speak HTTP/2 to the client.
  • Request tunnelling: when the connection is not shared between users but a second request can still be chained on top of the first to read hidden responses.

Real impact of a request smuggling attack

Smuggling is rarely the end goal: it is the pivot that enables other attacks.

  • Perimeter control bypass. The smuggled request reaches the back-end without passing the checks the front-end or the WAF apply to normal requests, granting access to internal or administrative endpoints.
  • Capturing other users' requests. By prepending a body that stores or reflects the next request, the attacker retrieves session cookies, tokens and authentication headers from real victims.
  • Web cache poisoning. Combined with an intermediate cache, a manipulated response is stored and served to every later user of that URL.
  • Escalation into other vectors. Smuggling can be chained with SSRF to reach internal services, or with open redirects to steal credentials. As with almost everything in offensive web security, critical impact comes from chaining, not from a single flaw.

Detection with Burp Suite and other tools

Request smuggling is detected by differential behavior, not by static signatures. The two main signals are timing (a malformed request causes a delay because the back-end waits for bytes that never arrive) and differential response (the attacker's request affects a follow-up request).

  • HTTP Request Smuggler. The PortSwigger extension for Burp Suite, built on James Kettle's research, automates timing-based detection of CL.TE and TE.CL, helps construct the attack and validates the desync without degrading service for real users.
  • Turbo Intruder. Lets you send concurrent requests over the same connection to confirm that one request influences another, essential when validating impact.
  • smuggler.py. A Python tool that systematically tries dozens of Transfer-Encoding header mutations to discover which obfuscation each end accepts.
  • h2csmuggler. Aimed at abusing cleartext HTTP/2 upgrades (h2c) that sometimes allow tunneling requests to the back-end.

The responsible process always runs in authorized environments with low-footprint techniques: smuggling tests can disrupt third-party requests, so they are executed within agreed windows and favor timing-based detection over destructive exploitation.

CVEs and real cases

Smuggling is neither theoretical nor exclusive to custom software. It has affected reference servers:

  • CVE-2019-20372 in nginx: the error_page directive allowed injecting a request into the flow under certain configurations.
  • CVE-2021-33193 in Apache HTTP Server (mod_http2): crafted HTTP/2 requests caused smuggling when forwarded.
  • CVE-2023-25690 in Apache (mod_proxy with malformed RewriteRule/ProxyPassMatch rewrites): allowed splitting the request and poisoning the cache or bypassing access controls.
  • Runtimes like Node.js have published multiple advisories tied to the llhttp parser due to lax interpretation of length headers.

The pattern repeats: when two different implementations share a request, any deviation from the RFC becomes attack surface.

Defenses: normalization and architecture

Effective countermeasures act at the point where the ambiguity is born.

  • Normalize or reject at the front-end. The edge must reject any request that includes both Content-Length and Transfer-Encoding, or any obfuscated or duplicated Transfer-Encoding, as RFC 9112 recommends. If the front-end normalizes the request before forwarding, the back-end receives something unambiguous.
  • End to end HTTP/2 with no downgrade. Keeping HTTP/2 between the front-end and the back-end too removes the HTTP/1.1 rewrite that enables H2.CL and H2.TE. If the downgrade is unavoidable, the rewritten headers must be strictly validated.
  • Consistent front-end and back-end. Using the same software and version, or at least servers that apply identical parsing criteria, reduces the chance of disagreement.
  • Disable connection reuse to the back-end. This is the brute-force mitigation: with no shared connection there is no victim request to contaminate. It carries a performance cost, so it is kept as a safety net.
  • Patch the whole chain. Proxies, CDNs, load balancers and application servers must be patched against the known CVEs.
  • Test periodically. Including smuggling in the scope of web application penetration testing ensures that architecture changes do not reintroduce the vector.

Frequently asked questions

Does HTTP request smuggling also affect HTTP/2?

Yes, though indirectly. HTTP/2 uses explicit frame lengths and should not be ambiguous, but most deployments downgrade to HTTP/1.1 toward the back-end. At that point the H2.CL and H2.TE variants reappear. The robust defense is to keep HTTP/2 end to end or to validate the rewrite rigorously.

Does a WAF protect against request smuggling?

Only partially. A signature-based WAF can block known payloads, but the essence of the attack is precisely to smuggle a request that the WAF does not inspect with the same criteria as the back-end. Worse, a WAF and the application server can form the desynced pair themselves. The real protection is request normalization, not pattern detection.

What is the difference between CL.TE and TE.CL?

The difference is which header each server prioritizes. In CL.TE the front-end honors Content-Length and the back-end honors Transfer-Encoding. In TE.CL it is the reverse. The direction of the desync changes how the chunked body is built and which fragment gets smuggled into the next request.

How is it detected without breaking production?

Responsible detection relies on timing, not exploitation. Burp's HTTP Request Smuggler extension sends requests that, if a desync exists, cause a measurable delay without poisoning real requests. Only after confirming the vector in a controlled environment is impact validated, and always within an agreed window.

Is it an application flaw or an infrastructure flaw?

Almost always infrastructure and its configuration: the vulnerability lives in the chain of proxies and servers, not in the business code. That is why the platform team is key to remediating it, even though the finding surfaces during an application audit.

How we handle request smuggling at Secra

At Secra we include HTTP request smuggling within the scope of web audits based on OWASP WSTG, with timing-based detection, controlled impact validation and concrete normalization recommendations for the platform team. The goal is not only to confirm the desync, but to document the responsible chain of servers and verify that the applied mitigation closes the vector without degrading performance.

If your organization operates behind CDNs, reverse proxies or gateways and you want to validate that the chain is not vulnerable to smuggling, you can reach us through contact or check the web and mobile audit service.

About the author

Secra Solutions team

Ethical hackers with OSCP, OSEP, OSWE, CRTO, CRTL and CARTE certifications, 7+ years of experience in offensive cybersecurity, and authors of CVE-2025-40652 and CVE-2023-3512.

Share article