Repository navigation
pip 24.0.post4 (Py3.7): vendored urllib3 1.26.20.post4; requests CVE-2024-47081, CVE-2026-25645 - #16
Merged
Conversation
…2024-47081, CVE-2026-25645 - Vendored urllib3 1.26.17 -> ActiveState urllib3 1.26.20.post4, vendored by replaying pip 24.0's own vendoring diff against upstream 1.26.17 onto the fork's src/urllib3 (pip._vendor imports, Brotli disabled, LICENSE.txt). The result is byte-identical to the urllib3 vendored in pip 26.0.1.post3. urllib3.__version__ stays "1.26.20" so requests' version check does not warn. - Vendored requests 2.31.0: backport CVE-2024-47081 (get_netrc_auth uses the parsed hostname, psf/requests 96ba401c, 2.32.4) and CVE-2026-25645 (extract_zipped_paths uses mkstemp, psf/requests 66d21cb07b, plus the companion e331a288f3 cert_verify change). - CVE-2024-35195 not ported: pip never mixes verify=False and verify=True on one adapter.
ezequielp-activestate
approved these changes
Oct 29, 2026
ezequielp-activestate
left a comment
There was a problem hiding this comment.
Approving. I found no blockers.
What I checked
- Vendored urllib3:
src/pip/_vendor/urllib3is byte-identical to the 26.0.1.post3 tag, which I checked earlier against the 1.26.20.post4 sdist plus pip's vendoring changes. The decompression limits (max_lengthin the Deflate, Gzip and Brotli decoders) are present. - CVE-2024-47081: the
get_netrc_auth()hunk is psf/requests 96ba401c line for line. - CVE-2026-25645:
extract_zipped_paths()andcert_verify()match the 26.0.1.post3 backport (66d21cb07b + e331a288f3). - CVE-2024-35195 not ported: I agree.
session.pymounts the verifying adapter onhttps://, and the only adapters withverify=FalseareInsecureHTTPAdapterandInsecureCacheControlAdapter, whosecert_verify()always forces it. The only other place pip setsverifyissession.verify = options.cert. So no single adapter's pools see both modes. - Built from this branch with
python -m build, tested onpython:3.7:- Versions: pip 24.0.post4, requests 2.31.0, urllib3 1.26.20, certifi 2026.10.23. Importing them under
-W error::Warningraises nothing. - netrc:
get_netrc_auth("http://example.com:@attacker.com/")returns attacker.com's entry, andhttp://example.com:8080/still returns example.com's. - Zip extraction: with a planted
cacert.pemin the temp directory,extract_zipped_paths()returns the zipped content at a new path on every call. - Network:
pip download six==1.16.0,pip install --dry-run requests==2.31.0, andpip downloadrun from inside the wheel all work.
- Versions: pip 24.0.post4, requests 2.31.0, urllib3 1.26.20, certifi 2026.10.23. Importing them under
- Diff from the 24.0.post3 release asset: only the 13 files listed in the description plus
dist-info. My local wheel's sha256 differs from yours (556b4c3e…) only because of build timestamps.
🟡 Non-blocking, upstream follow-up in the same function: psf/requests 47914226c2 ("Fix empty netrc entry usage", 2.33.x) makes get_netrc_auth() ignore an entry with no login and no password. Without it, a bare default line in .netrc returns ('', '') for every host, so pip sends empty Basic credentials instead of falling through to keyring or a prompt. It has no CVE and leaks nothing. It's a one-line change (if _netrc and any(_netrc):) if you want it here and in 26.0.1.post3.
icanhasmath
added a commit
to ActiveState/cpython
that referenced
this pull request
Oct 29, 2026
pip 24.0.post3 still vendored urllib3 1.26.17 and an unpatched requests 2.31.0. ActiveState pip 24.0.post4 (ActiveState/pip#16) vendors ActiveState urllib3 1.26.20.post4 (CVE-2023-45803, CVE-2024-37891, CVE-2025-50181, CVE-2025-66418, CVE-2025-66471, CVE-2026-21441, CVE-2026-44431, CVE-2026-97687, CVE-2026-97689) and backports the requests fixes for CVE-2024-47081 and CVE-2026-25645. certifi stays at 2026.10.23. The wheel is the release asset, sha256 749401b66b9dee893c560b12b8ee3b6f2d2d3600bdc047350c1a9d6db9047c17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Security release pip 24.0.post4 for the Python 3.7 line, to be bundled by CPython 3.7.17.8's
ensurepip. pip 24.0.post3 still vendored urllib3 1.26.17 and an unpatched requests 2.31.0.Changes
Vendored urllib3 1.26.17 → ActiveState urllib3 1.26.20.post4. This picks up upstream 1.26.18/1.26.19 and the fork's 1.26-line ports:
Proxy-Authorizationkept on cross-origin redirects (upstream 1.26.19)Content-Encodingdecoder chainPoolManagerretriesdid not limit redirectspip/_vendor/urllib3) and replayed it onto the fork'ssrc/urllib3from the 1.26.20.post4 sdist. The only hunk that didn't apply was aimport six→from pip._vendor import sixfix incontrib/securetransport.py; that targets an upstream 1.26.17 bug fixed in 1.26.18, and the fork already imports..packages.six. The vendored tree is byte-identical to the urllib3 in pip 26.0.1.post3 (pip 26.0.1.post3 (Py3.9): vendored urllib3 1.26.20.post4; requests CVE-2026-25645 #15).python_requires=">=2.7, !=3.0.*, …, !=3.5.*".urllib3.__version__stays1.26.20, so requests' version check doesn't warn.Vendored requests 2.31.0 (the last requests for Python 3.7, so it stays at 2.31.0):
get_netrc_auth()split the netloc at the first:, sohttp://example.com:@attacker.com/looked up, and sent, example.com's.netrccredentials to attacker.com. It now uses the parsed host name. pip calls it fromMultiDomainBasicAuthfor index and find-links URLs, so pip was exposed.extract_zipped_paths()now extracts to a newmkstempfile, andHTTPAdapter.cert_verify()uses the default CA bundle path directly. pip didn't reach the vulnerable path, so this is defense in depth.verify=Falsewas reused by later verified requests to the same host.--trusted-hosthosts are mounted on their ownInsecureHTTPAdapter, which forcesverify=False, and everything else goes through the verifying adapter.HTTPAdapter.get_connection()and needed 2.32.1–2.32.3 to stop breaking custom adapters like pip's_SSLContextAdapterMixin.pip-level advisories: every pip advisory that affects 24.0 is already fixed on this line, so nothing new is needed:
Certifi stays at 2026.10.23.
Validation
pip wheel built with
python -m build, tested inpython:3.7-slim(Python 3.7.17):-W error::Warningraises noRequestsDependencyWarning..netrcthat has entries for example.com and attacker.com,get_netrc_auth("http://example.com:@attacker.com/")returns attacker.com's entry. 24.0.post3 returned example.com's credentials.http://example.com:8080/still gets example.com's entry.cacert.pemin the temp directory,extract_zipped_paths()returns a new file with the zip's content, not the planted file, and a different path on every call.pip download six==1.16.0and apip install --dry-run requests==2.31.0resolution against PyPI both work.python pip-24.0.post4-py3-none-any.whl/pip download six==1.16.0works.pip/__init__.py,vendor.txt,requests/adapters.py,requests/utils.pyand nine urllib3 files, plusRECORDandMETADATA. The urllib3 files in the wheel are identical to the vendored tree in this PR.5bb693cb7b5bada4be8e0620c2fdc714f6f8c4c0cc2dda83f27912039739e974(local build).After merge: tag
24.0.post4and publish the release. Then bundle it in CPython 3.7.17.8.