Date discovered: May 2023  
Status: Patched in Requests v2.31.  
Severity: High

Introduction

Requests is one of the most popular HTTP libraries in the Python ecosystem. Developers use it for a wide range of purposes, from basic data scraping to building full-featured web clients. But in 2023, a critical vulnerability—CVE-2023-32681—was found. This bug meant Requests could accidentally leak your proxy credentials to the very web servers you might be trying to hide them from.

Let’s break down what happened, how it worked, show a code example, and what you should do if you use Requests.

What Is CVE-2023-32681?

The core issue: When following redirects from HTTP to HTTPS while behind a proxy, Requests could leak your Proxy-Authorization credentials directly to the web server.

This leak exposes sensitive data—such as usernames and passwords meant only for your trusted proxy—to any remote server. If an attacker controls the destination server, they'd be able to capture and misuse these credentials.

How Did This Vulnerability Occur?

*Since Requests 2.3. (June 2014),* the library used a helper called rebuild_proxies to reattach the Proxy-Authorization header whenever a request was retried (such as after a redirect).

Normally, for HTTP requests through a proxy, the proxy handles this header—it removes it before passing the request on to your destination server, so the web server never sees your credentials. But for HTTPS requests, things are different:

- HTTPS Proxying: The client first issues a CONNECT request with the Proxy-Authorization header. The proxy authenticates, creates a tunnel, and direct encrypted traffic flows between the client and the destination.
- If Requests mistakenly attaches the Proxy-Authorization header to a *normal* HTTPS request (not the CONNECT step), this header will be sent straight to the destination server after a redirect.

Code Example: Triggering the Leak

Let’s see an example that highlights the bug.  
Suppose you use an HTTP proxy that requires authentication. You make a request to a URL that responds with a redirect to an HTTPS address:

import requests

proxies = {
    'http': 'http://user:pass@proxy.example.com:808';,
    'https': 'http://user:pass@proxy.example.com:808';,
}

# This endpoint will redirect HTTP to HTTPS
url = 'http://destination.example.com/redirect-to-https';

response = requests.get(url, proxies=proxies)
print("Final URL:", response.url)

In vulnerable versions (requests <2.31.):

Requests would follow the redirect from HTTP to HTTPS.

- It would mistakenly send the Proxy-Authorization header along with the first HTTPS request not just to the proxy, but as part of the normal request headers to the destination server itself!

How Was It Fixed?

The Requests maintainers fixed this bug in version 2.31. (June 2023).  
The new logic ensures that headers meant only for the proxy are no longer reattached if the request is being sent directly to a destination server as part of a redirected HTTPS connection.

See the patch:  
- Commit fixing CVE-2023-32681
- Requests 2.31. changelog

Official advisory:  
- GitHub Security Advisory GHSA-j8r9-6ggf-6pwx
- NVD Entry for CVE-2023-32681

Proving the Bug: Minimal Exploit Example

You can see the dangerous behavior for yourself. Here’s a simple way to demonstrate the leak (for learning purposes, do _not_ leak your real passwords):

Sample Python code using a custom HTTPS server with logging might look like

from flask import Flask, request
app = Flask(__name__)

@app.route('/', methods=['GET'])
def index():
    # Log all headers and return to client for demo
    print(request.headers)
    return dict(request.headers)

if __name__ == "__main__":
    app.run(ssl_context='adhoc', port=4443)

If you run a vulnerable Requests version and have your proxy/redirect set up, you'll see Proxy-Authorization being printed in the HTTPS destination's log—something that should never happen.

What Should You Do?

1. Upgrade Immediately  
If you use Requests and rely on proxies (especially if those proxies require authentication), update to Requests 2.31. or newer:

pip install --upgrade requests

2. Regenerate or Rotate Credentials
If you suspect you may have been vulnerable in the past, generate new proxy credentials and clean up any old ones.

3. Audit for Proxy Usage
Review codebases for any custom handling of requests, proxies, or headers.

Summary

CVE-2023-32681 shows how a subtle detail in HTTP/HTTPS proxying can have big security consequences—even for the world's most popular libraries.  
If you use Requests—especially with a proxy—don’t delay upgrading. Stay safe out there!

Further reading

- Original pull request with fix
- Official Requests Docs
- Github Advisory Database entry


*Stay secure, and always keep your dependencies up to date!*

Timeline

Published on: 05/26/2023 18:15:00 UTC
Last modified on: 06/02/2023 18:17:00 UTC