The main origin of this vulnerability is the fact that the **reverse proxy** is going to **talk with the client** using **HTTP/2** but then it will **transform** that **communication** with the **back-end server** to **HTTP/1.1**.
The problem with this approach is that the **user** is going to be able to **inject** unnecessarily **headers** in the **HTTP/2 communication** that probably **won't be checked** by the proxy. But then, when those are **injected blindly in the HTTP/1.1 communication**, **a request smuggling attack can be performed**.
## Examples
### H2.CL Desync
The HTTP/2 specification indicates that the **Content-Length header isn't needed but can be indicated**. Therefore, the **reverse proxy** will **treat all the content sent by the users** as the request, but then, when **downgrading to HTTP/1.1**, this **header** is going to be **injected** in the **request** and therefore, the **back-end will treat the request as 2 different requests** as you can see in the image below:
![](<../../.gitbook/assets/image(639).png>)
### H2.TE Desync URL Token Hijack
The HTTP/2 specification also indicates that **any message containing connection-specific header fields MUST be treated as malformed... but if you don't follow this rule, you are vulnerable**.
This technique was abused on AWS load balancer, so making sure that the users access a Host header pointing to a server controlled by the attacker will make them access that server.
![](<../../.gitbook/assets/image(631).png>)
### H2.TE Desync Header Hijack
This is exactly the same technique as before, but checking the requests James noticed that clients were asking to send him their credentials, so he just modified his server to allow CORS to send him peoples credentials:
**HTTP/2 also won't allow to put not permitted characters in headers**, but if the server **isn't respecting** this rule, you can **inject arbitrary headers** when the communication is **downgraded** to HTTP/1.1.
Sometimes you will find that preforming a HTTP Request Smuggling attack **you can only attack yourself**. This could be because the reverse proxy has decided to **use a different connection with the back-end** server per IP.
Note that **even** with that **restriction** you still can perform attacks like **authorization bypasses**, internal headers leakage and **cache deception and cache poisoning** attacks.
Usually this restriction doesn't exist so you can **smuggle request into the connection between the reverse proxy and the back end** that other people are using, but it's even **possible** that the **proxy** doesn't **even reuse a connection with connections from the same IP** (pretty heavy restriction for this kind of attack).
In the heaviest restriction (no connection reuse) you will detect the vulnerability with the Time Based technique, but then testing it you will find that it's a "false positive".
The **problem** with **HTTP/1.1** is that if you **receive 2 HTTP responses** you **don't know** if the endpoint was **vulnerable** or it isn't and the **"smuggled" request was just treated as a regular request**.
However, this technique can be used **in HTTP/2** because if the endpoint was **vulnerable** and you smuggled one request, you will see the **headers of the response to the smuggled request in the response from the reverse proxy**:
There could be another problem, if the **response** to the legit request **contains** a **Content-Length**, the **reverse prox**y is only going to **read the bytes specified there and no more, so you won't be able to read the response from the smuggled request.**
However, the **HEAD** request **doesn't contain a body** but it usually **contains** the **Content-Length** as if the request was a GET request. Therefore, sending a **HEAD** request **instead of a POST** request you can **read the HEAD Content-Length** bytes of the smuggled request response.
If you find a **POST****parameter** inside the application whose **content** is going to be **reflected** in the **response**, then you can try to inject HTTP/1.1 \r\n characters inside a HTTP/2 request header so the newly injected headers by the proxy are going to be appended in the POST parameter that will be reflected in the response:
Note that in this case the **attacker** just cares about the **response** to the **first****request**, he doesn't need to read the request to the smuggled invalid second request.
{% hint style="info" %}
Using this attack **agains different parts of the web (method, path...)** can lead to different back-ends being used and **different sensitive information being leaked**
{% endhint %}
### Cache Poisoning via Tunneling
In this scenario a **HEAD** request to the **URL****whose****cache** is going to be **poisoned** is sent while **smuggling** a **request** whose **response content will be containing the payload** (maybe some XSS payload).
Due to the fact the the **HEAD response contains the `Content-Type: text/html`** and because the reverse proxy thinks that the **whole response to the smuggled request is the body of the HEAD** request, the **XSS payload** is going to be **treated as HTML** even if the page wasn't vulnerable to XSS.
* This talk explains perfectly all the techniques indicated here: [https://www.youtube.com/watch?v=rHxVVeM9R-M](https://www.youtube.com/watch?v=rHxVVeM9R-M)