Python October Security Patches: Verify the Runtime and Trust Store
As of October 27, 2026, Python has expedited security releases worth separating from routine dependency updates. The October 26 announcement lists 3.15.2, 3.14.10, 3.13.18, 3.12.16, and 3.11.18. All five block compromised eMudhra intermediate CA keys in ssl, tighten tarfile.tar_filter, and reject negative cookie versions. The last three are source-only releases; 3.15 and 3.14 also have binary installers.
Three separate upgrade decisions
First, identify the interpreter and its supplier. An upstream Python build should meet the applicable release floor. A distribution package may retain an older upstream version while backporting a fix. Require the distributor’s advisory and exact installed package revision as evidence; a version string alone cannot settle that case. Do not replace a distribution’s system Python with a manually compiled binary.
Second, inspect the TLS library and trust configuration. Python’s SSL reference documents default verification paths and secure context construction. A runtime fix, an operating-system CA update, and a package-managed certificate bundle are different inputs. A successful pip upgrade does not prove the interpreter was patched; a CA-file timestamp does not prove compromised intermediate keys are blocked. Applications can supply their own CA bundles or contexts.
Third, rebuild and restart the application environment. Record the interpreter used by the service, scheduled job, container, and virtual environment, not just your interactive shell. Install through the established supplier, recreate environments when required, and rerun application tests with the replacement interpreter.
Run an inventory in a scratch directory
Use Bash and the runtime your application actually launches. These examples ran on Debian 13 Linux; executable paths and library versions will differ on your machine. Keep the same terminal open. Stop if setup fails:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Save this as audit-python.py:
import platform
import ssl
import sys
minimum = {(3, 15): 2, (3, 14): 10, (3, 13): 18, (3, 12): 16, (3, 11): 18}
version = sys.version_info
floor = minimum.get(version[:2])
print("Python:", platform.python_version())
print("Executable:", sys.executable)
print("TLS library:", ssl.OPENSSL_VERSION)
paths = ssl.get_default_verify_paths()
print("Default CA file:", paths.cafile)
print("Default CA directory:", paths.capath)
context = ssl.create_default_context()
print("Certificate verification required:", context.verify_mode == ssl.CERT_REQUIRED)
print("Hostname checking enabled:", context.check_hostname)
if floor is None:
result = "outside this advisory's five release lines; check support policy"
elif version.micro < floor:
result = "below upstream floor; check distributor backport evidence"
else:
result = "meets upstream version floor; still verify package provenance"
print("Inventory result:", result)Run it with the selected interpreter:
python3 -B audit-python.pyObserved output on the available CPython 3.12.14 runtime:
Python: 3.12.14
Executable: /opt/codex/runtimes/codex-primary-runtime/dependencies/python/bin/python3
TLS library: OpenSSL 3.5.8 25 Aug 2026
Default CA file: /etc/ssl/certs/ca-certificates.crt
Default CA directory: /etc/ssl/certs
Certificate verification required: True
Hostname checking enabled: True
Inventory result: below upstream floor; check distributor backport evidenceThis is a tested inventory check, not a successful upgrade or a vulnerability regression test. The available runtime falls below the upstream 3.12.16 floor; no distributor backport was verified. The two True values describe a newly created default context, not every context in an application. Default CA paths do not reveal all library-specific trust choices.
Verify the replacement before rollout
Record before-and-after output from the actual service interpreter. Check its package provenance and the supplier’s security advisory, then confirm the service was restarted into that build. In an isolated staging copy, run your application’s normal tests and exercise its real HTTPS, archive handling, and dependency installation paths. Keep certificate and hostname verification enabled. Never work around a failed test with an unverified context or disabled TLS verification.
Treat the version-floor result as a routing aid: it tells you which supplier evidence to collect. Even a passing floor check does not test certificate rejection, tar extraction defenses, or your application’s compatibility. Those behaviors were not exercised here. Retain the previous deployment artifact for a controlled recovery plan, while accounting for the exposure that returning to an unpatched runtime would reintroduce.
Clean up
rm -- audit-python.py
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect it before removing anything else.
Acknowledgements
This post was created with assistance from AI.