Security 11059 Published by

Python shipped expedited security releases across five active versions, 3.15.2, 3.14.10, 3.13.18, 3.12.16, and 3.11.18, to address the eMudhra/emSign compromised certificate incident (CVE-2026-115557). The main fix hardcodes a denylist of eight bad intermediate CA keys into the ssl module, making pip safe to use even before the tool itself is updated. Those two binary releases include over a hundred routine bugfixes, while the three source-only tracks add backported patches for the Expat XML parser, a Windows mimetypes issue, and a tempfile race condition. The team strongly recommends upgrading, and getting pip to 26.2.2 or newer remains essential since it trusts its own CA bundle separately from the system store.



Python Ships Expedited Security Fixes for Five Versions in Wake of CA Compromise

The new releases distrust eight compromised eMudhra certificates, which makes pip safe to use even before pip itself is updated.

Python's core team shipped expedited security releases for five active versions of the language Monday. The set covers 3.15.2, 3.14.10, 3.13.18, 3.12.16, and 3.11.18, and lines up around one nasty certificate authority compromise that changes how Python checks TLS connections.

Python

These aren't the usual feature drops. They're expedited patches that ship outside the normal October cycle, carrying only security fixes plus whatever else was already cooking for each track. The two binary ones, 3.15.2 and 3.14.10, also roll in a healthy chunk of routine maintenance. 3.15.2 stacks over a hundred bugfixes from roughly 70 contributors on top of the security work. The other three are source-only, aimed at people who build Python themselves or ship it in containers.

The eMudhra compromise

Here's what forced the rush. On October 20, eMudhra's own disclosure landed, and it was bad: the private keys of eight of its intermediate CA certificates, under its emSign brand, had leaked. These intermediates sit at the heart of the global trust web, chaining up to roots trusted by Mozilla, Microsoft, Apple, and Google, plus a pile of downstream stores.

The keys were weak in a way that's almost funny. Core developer Jacob "JacobCoffee" Coffee noted the elliptic-curve keys carried private values as low as d=4, with all eight coming in under d < 256. That's not a key. That's a number you could guess by hand, and with it, an attacker forges a certificate for any domain, impersonates the site, taps the traffic, and injects whatever they want, all while you're staring at a legit-looking padlock.

Browsers somehow stayed safe because these intermediates never showed up in Certificate Transparency logs, so CT-enforcing Firefox, Chrome, and Edge never even spotted the gap. But a huge swatch of non-browser clients, command-line tools, libraries, Electron apps like Slack and Discord, don't enforce CT, and those are exactly the things left exposed.

The proof part is the fun bit. The original reporter, going by "Wayne," actually signed a message with each of the eight private keys. The message itself: "We have a problem here - Wayne." He then sent the proofs to the root program teams, and you can still verify the whole thing offline with OpenSSL at a tracker site named after the incident, emudhra.we-have-a-problem.com. The root cause, filed in Mozilla's bug tracker, was just bad key generation dating back to April 2025, with no CT entries to catch it.

Here's the part that catches most people off guard. pip doesn't just trust your system's certificate store; it also loads its own vendored CA bundle, and there's no supported way to turn that off. So any pip older than 26.2.2 keeps trusting the bad intermediates no matter how hard you patch your OS. That's why Thomas Wouters (tiran) says plainly that "updating pip is the only reliable fix" for pip specifically.

Python's own addition is a defense-in-depth layer on top. It hardcodes a denylist of the compromised certs' public-key hashes straight into _ssl, bouncing any TLS chain built on a known-bad eMudhra key during verification. Mirror image of what Go already did back in the day. The net effect, per the blog, is that normal pip use, including upgrading pip itself, is now safe from these keys even if pip is still old, giving you a clean window to get everything current.

What's actually in the patch

Every version shares the same three fixes. Besides the eMudhra distrust (CVE-2026-115557), there's a tarfile issue (CVE-2026-114583) where symlinks with empty names could redirect extraction to a foreign directory, a path-traversal trick fixed by StanFromIreland. The third is a cookiejar bug (gh-160300) where a cookie carrying a negative Version slips past domain checks, letting any contacted server overwrite cookies for an unrelated domain. gpshead called it the set-side cousin of a years-old domain fix.

The three source-only releases bring more. They pick up an Expat bump to 2.9.0, closing an out-of-bounds read and a 32-bit integer overflow in the bundled XML parser, plus a Windows mimetypes fix that stops Python from reading user-writable known-files, and an email header edge case. 3.13 and 3.12 also grab a tempfile cleanup race-condition fix.

For what it's worth, it's worth a glance that 3.15 is otherwise a meaty release on its own. It landed on October 9 with lazy imports, a frozendict type, UTF-8 as the default encoding, unpacking in comprehensions, and a dedicated profiling package. These security releases are touching that newest track, but this batch has nothing to do with any of that. It's all about not getting MITM'd.

So what do you actually do? The team's advice is blunt: upgrade, and don't dawdle. The priority is pip. Get it to 26.2.2 or newer, since OS-level fixes alone won't cover pip's own bundle. You can still safely revive a broken pip by installing the wheel straight from pythonhosted with a pinned SHA-256 checksum, the browser's already-updated certificate store covers the transfer, so a MITM can't swap in a bad wheel.

Certifi wants 2026.10.19. uv users can point straight at the system trust store with UV_SYSTEM_CERTS=true uv self update. Container images that cache layers should be rebuilt with caching off, and images bundling an old CA store need rebuilding too. As of right now, some Docker official Python images still ship vulnerable pip, so keep an eye on docker-library/python#1142. If you're on Windows and can't patch immediately, calling mimetypes.init([]) is a fine stopgap.

The whole ecosystem got the memo in the days after disclosure. certifi, pip, uv, sigstore, conda, and pixi all shipped updates, and the OS vendors, CA bundle libraries, and other runtimes, Go, Node, Java, Rust, Deno, Bun, Dart, followed suit.

The releases are posted on python.org, and the announcement blog breaks down the full changelog per version. Grab the one for your track and get moving.