SERGIO RODRIGUEZSECURITY RESEARCH / 007

INDEPENDENT PATCH REPRODUCTION / 27 SEP 2026

CVE-2026-44431

The redirect.
The boundary.

urllib3 2.7.0 removes sensitive headers when a low-level proxied request follows a redirect to another origin. The same recorded call in 2.6.3 carries them across.

Compare the two releases
Headers meet an origin boundaryThe fixed release removes Authorization, Cookie, and Proxy-Authorization at the redirect. A benign control header continues to the second origin.ORIGIN AORIGIN BAUTHORIZATIONCOOKIEPROXY-AUTHORIZATIONCONTROL HEADER302 / CROSS-ORIGINREDIRECT BOUNDARY
FIXED PATH / DEFAULT REMOVAL POLICY
urllib3 2.6.3 → 2.7.06 CASES PER RELEASE / 12 PASSEDREAL REDIRECT CODE / CAPTURED TRANSPORT

01 / RECORDED TRACE

Follow what crossed.

Choose a case to compare the recorded headers. Select a release to inspect its captured calls. These are saved Python results; the browser displays the run.

Inspect a release

A low-level HTTPConnectionPool.urlopen call follows a cross-origin redirect through a proxy. The default policy names three sensitive headers for removal.

Headers on the redirected request

ACTUAL CAPTURE / BOTH RELEASES
Header presence at the last captured request in each release
Header2.6.3 Affected2.7.0 Fixed for this CVE
AuthorizationRetainedRemoved
CookieRetainedRemoved
Proxy-AuthorizationRetainedRemoved
X-Research-ControlRetainedRetained

urllib3 2.7.0 / FIXED

Loading the captured calls…

The complete trace is available in results.json.

Every value is a DUMMY marker. The Python harness replaces transport responses and blocks sockets and DNS; it still runs the release’s redirect implementation.

Reading the local result file…

02 / WHAT CHANGED

Same redirect.
Different headers.

The reproduced failure sits on the low-level path: HTTPConnectionPool.urlopen through a proxy. With the default removal policy, release 2.6.3 passes Authorization, Cookie, and Proxy-Authorization into the second captured request. Release 2.7.0 removes all three.

The high-level ProxyManager.request control strips the sensitive trio in both releases. That distinction matters: the affected API path is part of the finding, alongside the redirect and proxy conditions.

The custom-policy case adds X-Research-Control to the removal set. The fixed release removes that header too; the affected release retains it. An application’s explicit removal policy determines which headers it asks to strip.

Direct responses and disabled redirect following each produce one captured call. Their original headers stay on the original request, which is the expected control behavior.

03 / REPRODUCTION RECORD

A small experiment.
An exact pair of releases.

The original harness loads each pinned release wheel in an isolated Python subprocess, replaces HTTPConnectionPool._make_request with fixed responses, and captures the arguments passed to transport.

01 / PIN

Exact wheel bytes.

The record includes a SHA-256 for each tested wheel and each harness source file.

02 / EXERCISE

Real redirect logic.

The library chooses how to follow the redirect. Only the final transport operation is replaced.

03 / COMPARE

Six controlled cases.

Default headers, case handling, the high-level API, direct response, redirect controls, and a custom policy.

Recorded 27 September 2026 · Python 3.14.5 · Windows · 12 case expectations passed.

Inspect run provenance and hashes
See results.json for runtime, exact wheel hashes, and tested source hashes.
Reproduce the comparison

From the directory containing the downloaded harness and pinned manifest, acquire the exact wheels once, then replay from the local cache:

python -B run_replay.py --fetch
python -B run_replay.py

The first command downloads and verifies the pinned wheels into .cache/wheels. The second runs with those cached wheels. The README documents both steps.

04 / SOURCE & CREDIT

The report.
The reproduction.

The urllib3 advisory, GHSA-qccp-gfcp-xxvc, records CVE-2026-44431 and was published 7 May 2026. Original reporting is credited to christos-cantina-security, coordination to illia-v, and remediation review to sethmlarson.

My contribution here is the independent offline regression: an original harness, pinned releases, captured request arguments, and controls that separate the affected low-level path from the high-level API.

This run measures redirect argument handling with mocked transport. End-to-end proxy networking is outside the experiment. The version comparison concerns this CVE specifically.