Safeguard
Vulnerability Analysis

CVE-2023-32681: requests leaks Proxy-Authorization on red...

A malicious proxy could capture Proxy-Authorization credentials from Python's requests library when redirects crossed to HTTPS, before v2.31.0.

Vikram Iyer
Security Researcher
8 min read

CVE-2023-32681 is a credential-leak vulnerability in requests, the ubiquitous Python HTTP client used by an enormous share of the Python ecosystem's scripts, SDKs, and services. The flaw allows a Proxy-Authorization header — the credential a client presents to authenticate to an HTTP(S) proxy — to be forwarded to a destination server when a request made through an authenticated proxy is redirected to an HTTPS URL. In practical terms: if your code talks to a proxy that requires a username and password, and that proxy (or an attacker positioned as that proxy) issues a redirect, your proxy credentials can end up in the hands of whatever server the redirect points to. Given how routinely requests is used to call third-party APIs through corporate or vendor-managed proxies, this is a quiet but meaningful supply-chain-adjacent exposure: a single dependency behavior can turn a routine outbound HTTP call into a credential-disclosure event.

Affected versions and components

The vulnerability lives in the requests package on PyPI (the project also ships as the python-requests package on some Linux distributions). It affects the redirect-handling logic that has been present since requests added first-class proxy support, and it was fixed in requests 2.31.0. If your project, container image, or vendored dependency tree pins a requests version prior to 2.31.0 and your code (or a library you depend on) sets a Proxy-Authorization header — either explicitly or implicitly via trust_env picking up proxy credentials from the environment (HTTP_PROXY/HTTPS_PROXY with embedded credentials, or a .netrc-style configuration) — you are exposed.

This is not limited to application code that calls requests directly. Because requests is a foundational dependency for a huge number of Python SDKs, CLI tools, and higher-level HTTP clients (many of which wrap it transparently), the vulnerable code path can be several layers removed from anything a developer wrote themselves. Software composition analysis frequently finds requests as a transitive dependency in places engineering teams don't expect — data pipelines, cloud SDKs, CI/CD tooling, and internal automation scripts are all common carriers.

It's worth distinguishing this from the earlier, related requests issue (CVE-2018-18074), where an Authorization header could leak to a different host on redirect. CVE-2023-32681 is a distinct advisory specifically about the Proxy-Authorization header and proxy-authenticated flows, but it belongs to the same family of "sensitive header persists across a redirect to an unintended party" bugs that have periodically surfaced in HTTP client libraries. Any team that mitigated the 2018 issue should not assume that work also covered this one.

CVSS, EPSS, and KEV context

The vulnerability is tracked publicly as CVE-2023-32681 with a corresponding GitHub Security Advisory (GHSA-j8r2-6x86-q33q) published by the requests maintainers. It has generally been rated at Medium severity, reflecting the fact that exploitation requires a specific precondition — a proxy configuration with embedded authentication credentials combined with a redirect response, meaning the affected party typically has to be relying on (or be tricked by) a malicious or compromised proxy in the request path, rather than facing an internet-wide, unauthenticated attack surface.

It is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog, and we are not aware of confirmed in-the-wild exploitation. EPSS-style exploitation-probability scoring for this CVE has stayed low, consistent with a vulnerability that depends on a fairly specific network position (control of or influence over the proxy) rather than being remotely triggerable against arbitrary internet-facing targets. That combination — real credential-disclosure impact, but a narrower and more specific set of preconditions for exploitation — is exactly why this class of bug tends to be under-prioritized in vulnerability backlogs even though the consequence (a leaked proxy credential) can be severe if it happens: proxy credentials are frequently shared across many internal services, and a leaked credential can be replayed well after the original request.

Teams should not read "Medium" and "not in KEV" as "safe to ignore." Severity scores describe likelihood and blast radius under generic assumptions; they don't know whether your specific proxy credential also unlocks your internal network egress policy, your SSO-fronted proxy, or a credential shared across dozens of services.

Timeline

  • requests has supported proxy authentication via Proxy-Authorization since long before this advisory; the underlying redirect-handling behavior responsible for the leak was present across many historical releases.
  • The issue was reported to and triaged by the requests maintainers through their security disclosure process and tracked under GitHub Security Advisory GHSA-j8r2-6x86-q33q.
  • requests 2.31.0 was released in May 2023, containing the fix that strips the Proxy-Authorization header when a redirect would send the request to a different destination than the one the header was originally scoped to.
  • CVE-2023-32681 was published to the NVD shortly after the advisory and fixed release, making the fix and the vulnerability details public at essentially the same time — the standard "fix-then-disclose" pattern for responsibly handled open-source security issues.

Because the fix landed in a routine minor version bump (2.30.x → 2.31.0) rather than a headline-grabbing major release, it's easy for this upgrade to have been picked up silently by teams running loose version constraints, while teams pinning requests to an exact version or using older lockfiles remain exposed indefinitely until someone re-runs a dependency audit.

Remediation steps

  1. Upgrade requests to 2.31.0 or later. This is the definitive fix. Update requirements.txt, pyproject.toml, Pipfile, or equivalent, and regenerate lockfiles so the pinned version actually reflects the upgrade rather than just the declared constraint.
  2. Audit transitive dependencies, not just direct ones. Search your dependency graph (via pip show, pipdeptree, or your SCA tool of choice) for every copy of requests pulled in by SDKs, CLI tools, and internal libraries. A vulnerable transitive version defeats an upgrade to your direct dependency.
  3. Rebuild and redeploy affected artifacts. Container images, Lambda/serverless bundles, and pre-built wheels that baked in a pre-2.31.0 requests need to be rebuilt — a source-code change alone doesn't help if the vulnerable version is already frozen into a deployed image.
  4. Review where Proxy-Authorization credentials come from. If your services rely on trust_env (the default) to pick up proxy configuration from environment variables, confirm which environments embed credentials directly in HTTP_PROXY/HTTPS_PROXY URLs, and consider whether those credentials should be rotated as a precaution if you cannot rule out historical exposure through redirect-capable proxies.
  5. Constrain and monitor redirect behavior where feasible. For services that proxy sensitive or authenticated traffic, consider disabling automatic redirect-following (allow_redirects=False) for calls where a redirect is unexpected, and validate destinations before re-issuing requests manually.
  6. Add a regression check to CI. A simple dependency-version gate (failing the build if requests<2.31.0 is resolved anywhere in the tree) prevents this specific issue from silently reappearing via a downgraded transitive dependency or a relaxed version pin in the future.

How Safeguard helps

This CVE is a textbook example of why point-in-time dependency reviews aren't enough: requests is deeply embedded across the Python ecosystem, the vulnerable behavior is easy to miss because it only manifests under specific proxy-and-redirect conditions, and the fix arrived in what looked like a routine version bump. Safeguard is built to catch exactly this pattern.

  • Continuous SBOM and dependency graph visibility means Safeguard doesn't just check the requests version your project declares — it resolves the full transitive dependency tree across your services, container images, and build artifacts, so a vulnerable copy of requests pulled in three layers deep by an SDK is surfaced with the same clarity as a direct dependency.
  • Automated vulnerability matching against CVE and advisory feeds flags affected components like this one as soon as they enter your codebase or CI pipeline, tied to the specific fixed version (requests >= 2.31.0) rather than a vague "update your dependencies" nudge.
  • Policy-as-code gates in CI/CD let teams block merges or builds that would (re)introduce a known-vulnerable requests version, closing the exact gap that lets a fixed issue silently regress via a relaxed pin or an outdated lockfile.
  • Contextual risk scoring goes beyond a generic CVSS number by factoring in how the vulnerable component is actually used in your environment — for example, whether a service in your inventory is configured with authenticated proxy egress, which materially changes the real-world exploitability of this specific vulnerability compared to a service that never touches a proxy at all.
  • Remediation workflows and ownership routing turn a detection into an actionable ticket assigned to the team that owns the affected service, with the fixed version and required rebuild/redeploy steps attached, so the fix doesn't stall in a backlog the way header-leak bugs often do.

Vulnerabilities like CVE-2023-32681 rarely make headlines, but they're precisely the kind of quiet, dependency-buried risk that accumulates across a software supply chain when there's no continuous mechanism watching for it. Safeguard's goal is to make sure issues like this are caught, prioritized correctly, and closed out — not rediscovered months later during an incident review.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.