Skip to content

Build1 publisher2 min readPublished

Python 3.10.22 ends five years of security fixes for the 3.10 series

Python shipped 3.10.22 as the final release of the 3.10 series, with eight CVE fixes and no security updates after it. Any flaw reported from here on stays open on 3.10, so teams still running it have to move to a series that is still patched.

The Engineer · Build desk

Illustration accompanying Python 3.10.22 ends five years of security fixes for the 3.10 series

What happened

  • The 3.13 series has moved to security-only: 3.13.16 is its last full maintenance release, and every later 3.13 release will carry security fixes only.
  • Releases 3.10.22 and 3.11.17 are source-only, and 3.10.11 was the last 3.10 release to ship Windows or macOS installers.
  • Security support for 3.12, whose 3.12.15 release is also source-only, runs until October 2028.
  • On Windows, macOS and Android, 3.13.16 moves the bundled OpenSSL from 3.0.21 to 3.5.9, part of the 3.5 LTS series.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • exposure Anyone running 3.10 from a python.org Windows or macOS installer is on 3.10.11 at best, eleven releases behind the final source tarball.
  • constraint A Windows or macOS team that wants this sweep's fixes from a python.org installer has to be on 3.13 or 3.14.
  • decision Picking 3.11 to keep the upgrade small means the next forced migration comes in October 2027, a year before a team that picked 3.12 faces one.

On the day it ships, 3.10.22 has every CVE fix in this sweep [1]. That includes an XML hash-flooding protection for xml.parsers.expat and xml.etree.ElementTree [17], which 3.11 already received in 3.11.16 [20]. The release notes put it plainly: "If you are still using Python 3.10, please plan your upgrade to a supported version." [18]

Three of the fixes touch the same code, tarfile's extraction filters [2]. One closes a hole where hard links to symbolic links could expose files outside the destination and change their permissions or modification times [10]. The second stops a path that leaves the destination and comes back from creating directories outside it [11]. The third makes the filters apply when a link falls back to extracting an archive member [12]. If a fourth turns up, 3.11 can still get a fix and 3.10 will not [2][3].

The source-only releases leave two security dependencies to whoever builds them. They do not bundle OpenSSL [16], so TLS fixes come from the library the build links against. The new XML protection works only when Python is compiled with libexpat 2.8.0 or later [17]. The bundled libexpat is now 2.8.5 [15], so only builds linked against an older system copy miss the protection.

One fix is partial. CVE-2026-15310 bounds zipfile decompression per read for bzip2 and LZMA members, so small compressed members can no longer force unbounded allocations [13]. Code that monkey-patches _get_decompressor() with a third-party decompressor that lacks needs_input and a two-argument decompress() is still vulnerable after the upgrade [13].

The ssl fix is careful release engineering. Under CVE-2026-19553, ssl.SSLContext.wrap_bio() now validates its server_side, server_hostname and session arguments, and asyncio also validates the TLS server_hostname [8]. If a patch release started raising errors on a missing hostname, TLS clients that worked the day before would break. So when check_hostname is enabled and the hostname is missing, 3.10 through 3.12 emit a DeprecationWarning, and 3.13 and later raise ValueError [9]. That makes a 3.10.22 test run useful before a jump to 3.13. Each of those warnings marks a call that 3.13 will reject [9].

Python 3.10 got five years of security support [2]. The release notes started the series with a trip inside a Schwarzschild black hole, and they end it with the ringdown of a black hole formed in a merger [19].

What to watch

  • Whether the first security-only 3.13 release ships Windows and macOS installers, as 3.13.16 does, or goes source-only like 3.10 through 3.12.
  • The first CVE fixed on 3.11 and later after this sweep, since it will be the first fix 3.10 does not get.
  • Whether distributors that build 3.10 against a system libexpat older than 2.8.0 ship 3.10.22 without the hash-flooding protection.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories