This is a Python 3 implementation of CVE-2023-32681, affecting clients using the requests version <= 2.30.0.
As per https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4 whenever redirection 3xx is issued by the server then user-agent should modify the request to remove certain headers and fields from the request.
Details of those fields can be found at https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4-5. Specific to this CVE I've highlighted the relevant part here.
requests version <= 2.30.0 didn't remove the "Proxy-Authorization" headers while handling the redirection to "https" and thus leaking the proxy credentials to the redirected server.
More details for the same can be found at
- https://www.cve.org/CVERecord?id=CVE-2023-32681
- https://security.snyk.io/vuln/SNYK-PYTHON-REQUESTS-5595532
- Valid set of certificate for the HTTP(S) server. You can use mkcert to generate the certificates locally.
- Go v1.19
- Python 3.x
- virtualenv (Optional)
- Proxy server implementation in Go. It starts a proxy server on Port 8080 and requires a basic authentication. For the POC purpose, it has the hardcoded username and password defined in the same file.
- HTTP(S) server implementation in Go. It starts 2 servers.
- Redirection server listening on Port 443 and another echo server listening on Port 4431.
- Redirection server defines a route
/redirect
that redirects the traffic to second server running on 4431. - Echo server defines a route
/echoHeaders
. This route returns the headers it received in the request to the client.
- POC Python script. It issues a proxied request to redirection server running on port 443 and prints the response that server returns.
- If the response contains the
Proxy-Authorization
headers then therequests
version is said to be vulnerable to "CVE-2023-32681".
- Clone this repository.
- Update the
certFile
andkeyFile
variables inserver/main.go
. - Start the HTTP(S) servers by running command
go run server/main.go
. This will start two servers listening on port 443 and 4431. - Start the Proxy server by running command
go run proxy/main.go
. This will start the proxy server on port 8080. - Install dependencies to run the Python script
pip3 install -r script/requirements_request_2_30_0.txt
- Execute the POC script by running
python3 script/poc.py
and observe the output. You can see that "Proxy-Authorization" header is returned by the server in the response. Server also prints the received headers in the logs. - Now, upgrade the requests version to >= 2.31.0 or do
pip3 install -r script/requirements_request_2_31_0.txt
- Again execute the POC script by running
python3 script/poc.py
and observe the output. You can see that "Proxy-Authorization" header is now not present in the server response. Same can also be verified in the server logs.