Skip to content

3.10.22.1: eMudhra ssl distrust + 3.11.18 security fixes, ensurepip pip 26.2.2 - #87

Merged
icanhasmath merged 17 commits into
3.10.22.xfrom
3.10.22.1-security
Oct 28, 2026
Merged

icanhasmath merged 17 commits into
3.10.22.xfrom
3.10.22.1-security

Conversation

@icanhasmath

Copy link
Copy Markdown

ActiveState security release 3.10.22.1 of the end-of-life 3.10 line (upstream's last release was 3.10.22 on 2026-10-01).

Driven by the eMudhra / emSign CA key compromise (python.org advisory). Upstream fixed it in 3.11.18 and later, but will never fix 3.10.

What's in it

The 3.11.18 security set, cherry-picked with -x:

Fix Notes
pythongh-160040 ssl distrusts the compromised eMudhra intermediate keys (CVE-2026-115557) SPKI-SHA256 denylist in the verify callback. It applies even when an app supplies its own CA bundle (e.g. an old pip/certifi)
pythongh-160097 tarfile.tar_filter rejects links that replace the destination (CVE-2026-114583)
pythongh-160300 http.cookiejar negative cookie Version
pythongh-159428 mimetypes doesn't read knownfiles by default on Windows
pythongh-158876 bundled libexpat → 2.9.0
pythongh-87720 email header refolding/re-quoting
Sphinx :cve: markup needed by the new NEWS entries

It also upgrades ensurepip's bundled pip from 23.0.1 to 26.2.2. pip 23.0.1's vendored certifi still trusts the emSign root. Upstream bumped pip only on 3.13+, so this commit is ours. The wheel's sha256 fd7f4dfa…3a70 matches PyPI and the advisory.

The last commit sets PY_VERSION to 3.10.22.1 and adds a "Notable changes in 3.10.22.1" section to Doc/whatsnew/3.10.rst.

3.10 adaptations

Each one is described in the body of the commit it affects:

  • 3.10 builds expat and _ssl from setup.py, not from the Makefile.pre.in module lists. So xcs.c and distrusted_spki.h are wired in setup.py / Modules/Setup.
  • Test certs live in Lib/test/ (there's no certdata/).
  • The What's New entry goes in 3.10.rst.

Windows build customizations stay as Platform inventory patches and are not part of this branch.

Testing

Linux x86_64 with OpenSSL 3.0.13, out-of-tree build:

  • Full python -m test -j8 -u all,-network,-gui,-cpu,-largefile,-audio,-urlfetch: 396 OK, 0 failed.
  • After the version bump: test_sys test_platform test_sysconfig test_venv test_ensurepip test_ssl test_pyexpat pass, including the new test_distrusted_spki.
  • A fresh venv gets pip 26.2.2 with certifi 2026.10.19, and pip download from PyPI works.

Windows was not built.

After merge: tag v3.10.22.1 on the merge commit.

miss-islington and others added 11 commits October 27, 2026 14:08
…se (pythonGH-134271) (python#159065)

pythongh-87720 Fix additional header refolding-quoting edge case (pythonGH-134271)

In this case, the higher level syntactic unit fit on the remainder of
the line in un-encoded format, and that higher level unit was
not a ptext or vtext, so the encoding check failed.  To fix this, we
look inside the current unit to see if has anything that was
originally encoded.
(cherry picked from commit 5a22a62)

Co-authored-by: R. David Murray <rdmurray@bitdance.com>
(cherry picked from commit 26ee788)
… Windows (pythonGH-159445) (python#159573)

Make knownfiles empty on Windows so that only the registry is used by default. Files passed to init() or assigned to knownfiles explicitly are still read.
(cherry picked from commit 04a29bf)
(cherry picked from commit 35dd324)
… (python#160261)

(cherry picked from commit 0071fb5)
(cherry picked from commit 25f598d)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
(cherry picked from commit b370d7a)

3.10.22.x: 3.10 builds the bundled expat from setup.py, not from
LIBEXPAT_OBJS in Makefile.pre.in, so xcs.c is added to setup.py's
expat_sources (and xcs.h to expat_depends) instead.
…p.cookiejar (pythonGH-160301) (python#160649)

pythongh-160300: Reject cookies with a negative version in http.cookiejar (pythonGH-160301)

DefaultCookiePolicy only applied its domain checks to cookies with
version 0 or a positive version.

ANT-2026-TA36I7V7
(cherry picked from commit d59d968)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
(cherry picked from commit 6229895)
…rfile.tar_filter` (pythonGH-160098) (python#160343)

pythongh-160097: Reject links replacing the destination in `tarfile.tar_filter` (pythonGH-160098)
(cherry picked from commit e7e0b35)

Co-authored-by: Stan Ulbrych <stan@python.org>
(cherry picked from commit bc93f8a)
…keys (CVE-2026-115557) (pythonGH-160042) (pythonGH-160572)

The ssl module now rejects TLS certificate chains that contain any of a set of
compromised eMudhra intermediate CA keys.  This is an extraordinary measure and
a last line of defense: removing trust is primarily the job of the platform root
store, and the built-in denylist only blocks connections while that update has
not yet reached the OS, a container image, or a bundled trust store in various
Python packages.  Entries are added to the denylist only under a very high
threshold.

The denylist matches on the public key (the SHA-256 digest of the RFC-5280
SubjectPublicKeyInfo), so it also covers the cross-signed certificates that
reuse one of the distrusted keys.

(cherry picked from commit 7dd8b47)

Co-authored-by: Christian Heimes <christian@python.org>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
(cherry picked from commit af52b41)

3.10.22.x: 3.10 keeps the test certificates directly in Lib/test (no
certdata/ subdirectory) and builds _ssl from setup.py, so distrusted.zip
lands in Lib/test and distrusted_spki.h is added to the _ssl depends in
setup.py instead of MODULE__SSL_DEPS.
….10.22.1) (python#160591)

Signed-off-by: Christian Heimes <christian@python.org>
(cherry picked from commit e4f63e6)

3.10.22.x: the entry goes into Doc/whatsnew/3.10.rst under a new
"Notable changes in 3.10.22.1" section.
Upstream upgraded ensurepip's bundled pip to 26.2.2 only on 3.13+
(pythonGH-159910, cherry picked to 3.13 as d811ad4); the security-only
3.11 branch kept pip 24.0 and relies on the pythongh-160040 ssl denylist.
3.10 has no upstream release left, and the pip 23.0.1 it bundles
carries a vendored certifi that still trusts the compromised eMudhra
emSign root, so every venv created with ensurepip started out with a
pip that loads those CAs. pip 26.2.2 supports Python >= 3.10.

Wheel sha256 fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70,
matching PyPI and the hash published in the python.org eMudhra
advisory.
ActiveState security release of the end-of-life 3.10 line: the 3.11.18
security fixes that apply to 3.10 (including the pythongh-160040 eMudhra
distrust in ssl) plus ensurepip's bundled pip upgraded to 26.2.2.
…ython#160621)

The windows-2022 GitHub runner image no longer ships Python 3.10, so
PCbuild/find_python.bat fell through to NuGet and installed the latest
pythonx86 package, which is now 3.15.1. Python 3.15 removed
Loader.load_module(), which Python/makeopcodetargets.py used to import
Lib/opcode.py, so the _RegenOpcodes target failed and broke every
Windows CI build on this branch.

Load Lib/opcode.py through importlib.util instead, and extend the py.exe
search list in find_python.bat up to 3.14 so the build picks up the
runner's preinstalled Python rather than whatever NuGet considers latest.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 0fc0183)

3.10.22.x: 3.10's py.exe probe accepted 3.9 and 3.8; the new list keeps
3.8 as the floor and prefers 3.14 down to 3.9 first. Build tooling only;
needed so the Windows CI jobs build at all now that the runner falls
through to a Python 3.15 host.
serhiy-storchaka and others added 6 commits October 27, 2026 21:08
…nGH-143922, pythonGH-153067) (pythonGH-153137) (pythonGH-153287)

Combined backport of pythonGH-143922, which rejected all control characters,
and pythonGH-153067, which narrowed the check to NUL, CR and LF.  Other
control characters are valid in quoted strings and are sent quoted.

(cherry picked from commit 6262704)
(cherry picked from commit d0921ef)
(cherry picked from commit 2981822)

Co-authored-by: Seth Michael Larson <seth@python.org>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
(cherry picked from commit 71926d9)

3.10.22.x: 3.10 has no IMAP argument quoting (the _non_astring_char /
_quoted machinery is 3.13+), so only the NUL/CR/LF rejection is ported.
The test keeps the rejection check and checks that other control
characters are still accepted, without the 3.13 quoting assertion.
(cherry picked from commit b234a2b)

3.10.22.x: test import conflict only (3.10 imports asynchat/asyncore from
the stdlib, not test.support).
…ythonGH-150752)

RFC 9112 defines Content-Length as 1*DIGIT and chunk-size as 1*HEXDIG, but int() also accepts a sign, underscores, surrounding whitespace and an 0x prefix, so malformed framing values were parsed instead of rejected.

(cherry picked from commit 2eb2af8)
…http.client (pythonGH-159156)

pythongh-150752 started validating the Content-Length value against the
RFC 9112 grammar (1*DIGIT), but the compat32 header parser keeps
trailing SP/HTAB in the field value, so "Content-Length: 5 " is now
treated as a missing header. HTTPResponse then assumes that the
connection will close and read() blocks until the server closes it,
which never happens on a keep-alive connection.

RFC 9112, section 5.1 says that optional whitespace around a field
value is excluded by parsers. Strip SP/HTAB before the grammar check;
values such as "+5", "5_0" and "5 0" are still rejected.

(cherry picked from commit 9f52b44)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
setuptools 79.0.1 is affected by CVE-2026-59890 (GHSA-h35f-9h28-mq5c,
MANIFEST.in exclusion bypass via Unicode normalization, fixed in 83.0.0)
and GHSA-xmj3-9gf7-h52w (Windows path escape via namespace_packages.txt
in legacy wheel-as-egg installation, fixed in 84.1.0). 84.2.1 is the
latest release and supports Python >= 3.10.

setuptools 82.0.0 removed pkg_resources, so venvs seeded by ensurepip
no longer have it.

Wheel from PyPI, sha256
ca140b45d5325a9478f880e351484f62fef15f336462e449ca0c03c873d589c2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ezequielp-activestate ezequielp-activestate left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers. Approving, with one behaviour change that needs a deliberate yes (below).

What I checked

  • Coverage. Every security fix in upstream 3.11.18 (v3.11.17..v3.11.18) is here: eMudhra distrust and its What's New entry, tarfile.tar_filter link replacement, negative cookie Version, mimetypes.knownfiles on Windows, Expat 2.9.0, email header re-quoting, and the :cve: Sphinx markup. The two 3.11.18 commits left out (VS 18 build support and a gdb test tweak) aren't security fixes. Among the 3.12 security-branch fixes since 3.10.22, the ones not here either don't exist on 3.10 (tomllib key limit, getpath.py Setup.local landmark, asyncio sock_recvfrom_into, perf trampoline) or are in the separate 3.10.22.2 tempfile PR.
  • Follow-ups. For each ported issue I looked for later commits on upstream main, 3.14 and 3.13. The only fix-of-a-fix is imaplib's pythonGH-153067, which narrowed the control-character check, and it's included. The http.client change carries both pythonGH-150752 and the pythonGH-159156 whitespace follow-up.
  • Diff against upstream. Cookiejar, mimetypes, email, tarfile, and both http.client commits are patch-identical to upstream. The other differences are the ones described in the commit bodies: setup.py wiring for xcs.c and distrusted_spki.h, 3.10's imaplib having no argument quoting, and doc/NEWS wording. Modules/_ssl/distrusted_spki.h and the _ssl.c hunk are byte-identical to upstream 3.11.
  • Wheels. pip-26.2.2-py3-none-any.whl (fd7f4dfa…3a70) and setuptools-84.2.1-py3-none-any.whl (ca140b45…89c2) match PyPI exactly. Both declare Requires-Python >=3.10.
  • Build and tests (Debian, OpenSSL 3.5.7, base 3.10.22.x vs head 580267d7):
    • Targeted modules: 30 security-relevant modules (test_ssl, test_tarfile, test_zipfile, test_email, test_httplib, test_http_cookiejar, test_urllib*, test_xml_etree*, test_pyexpat, test_sax, test_minidom, test_ensurepip, test_venv, test_imaplib, test_poplib, test_mimetypes, test_sys, test_platform, test_sysconfig, test_distutils and others): all pass on both.
    • Full suite (-u all,-network,-gui,-cpu,-largefile,-audio,-urlfetch): head 391 OK, base 392 OK. The same 12 modules fail on both, from running as root in a container. The one head-only failure, test_multiprocessing_fork, passes on both when run alone.
    • New tests: test_distrusted_spki and the five new tarfile ReplaceTests pass. pyexpat.EXPAT_VERSION is expat_2.9.0 on head, expat_2.8.5 on base.
  • Behaviour, base → head:
    • http.client with Content-Length: +5 / 5_0 gives length 5 / 50 on base and is ignored on head. 5 gives 5 on both.
    • imaplib select('INBOX\r\nA1 DELETE x') raises ValueError on head.
    • A head venv gets pip 26.2.2 and setuptools 84.2.1.

🟡 Needs a deliberate yes: setuptools 84.2.1 removes pkg_resources from every venv. On 3.10, python -m venv and ensurepip still install setuptools, so after this patch release a fresh venv has no pkg_resources: import pkg_resources gives ModuleNotFoundError. That breaks apps that import it, and legacy console scripts generated with pkg_resources entry-point loaders (setup.py develop / egg installs). It's documented in What's New and NEWS, and no setuptools release with pkg_resources (< 82) has the CVE-2026-59890 fix (83.0.0). Both setuptools issues only bite when building or installing untrusted sdists/eggs, though. Shipping 79.0.1 again is the lower-risk choice for a patch release on an EOL line. If you keep 84.2.1, it's worth stating the compatibility break in the release announcement as well.

⚪ Minor: the PR description lists only the 3.11.18 set and pip. It doesn't mention the imaplib, poplib, http.client and setuptools commits; What's New does.

Not assessed: Windows (not built); network-resource tests; the eMudhra digests against the actual certificates (the header is identical to upstream's).

@icanhasmath

Copy link
Copy Markdown
Author

Accepting the standard core setuptools drops pkg_resources.

@icanhasmath
icanhasmath merged commit 89af4ad into 3.10.22.x Oct 28, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.