A Python build can still trust an eMudhra certificate chain that browsers have blocked. Compromised intermediate CA keys create a way to impersonate an HTTPS package index if an attacker also intercepts or redirects the connection. That puts pip, uv, virtual environments and CI images that download dependencies through affected trust stores in scope. StepSecurity’s vendor research tested supplied chains against an older certifi bundle: it accepted seven of fourteen; corrected certifi and pip bundles rejected all fourteen.
Check the downloader even if the machine’s browser rejects the chain. An HTTPS response carrying a dependency can look authentic to a client that still accepts the affected chain. StepSecurity says whether attackers exploited this weakness against non-browser clients remains unknown. Update stale CA stores; investigate unexpected downloaded artifacts or process execution as separate compromise evidence.
The compromised chain reaches Python
A TLS client follows a certificate chain from the server through an intermediate authority to a trusted root. The certifi maintainers say emSign roots had intermediates revoked after key compromise. They first removed the affected roots in certifi 2026.10.18; StepSecurity recommends certifi 2026.10.19 or later because that release restores unaffected roots while retaining the security change. A downloader with an old bundle may still accept a chain built through a compromised intermediate. Interception or redirection is also needed for an attacker to deliver the forged HTTPS response.
StepSecurity, a CI/CD security vendor evaluating this risk, verified fourteen published chains with isolated bundles and OpenSSL hostname and server-purpose checks. certifi 2026.07.22 accepted seven paths through the emSign root, while certifi 2026.10.19 and the bundle inside pip 26.2.2 rejected all fourteen. Those are bundle-specific tests; apply the same trust decision to the actual client configuration in your job.
Pip keeps another certificate bundle
Current pip documentation says pip uses system certificates in addition to certifi by default. The pip changelog records a vendored certifi upgrade to 2026.10.19 in pip 26.2.2. Updating the project’s standalone certifi installation leaves pip’s vendored bundle in place. An OS certificate update also leaves a separate old bundle to check. Inspect PIP_CERT, REQUESTS_CA_BUNDLE and CURL_CA_BUNDLE where those settings select a different bundle.
The uv maintainers patched their default bundled roots in uv 0.13.4. Their advisory says, “Users are affected if they use uv’s bundled CA certificates, which are used by default.” For --system-certs, SSL_CERT_FILE or SSL_CERT_DIR, check the selected store for trust in the compromised roots or intermediates. A uv binary installed separately from a Python environment needs its own version check.
New environments inherit their interpreter
The Python ensurepip documentation says an interpreter carries the pip wheel it uses to bootstrap an environment. Its --upgrade operation uses bundled components and never goes online. StepSecurity reproduced the trap: after upgrading pip in a disposable Python 3.14.7 environment to 26.2.2, the parent interpreter’s ensurepip.version() still returned 26.2.1. A freshly created virtual environment can therefore start with an older downloader even after an existing environment has been repaired.
Run python -m pip --version, python -m pip show certifi and python -c "import ensurepip; print(ensurepip.version())" using the interpreter that builds each environment. Some distributor builds omit ensurepip; follow the distributor’s Python update path there. An installed pip version and a seed-wheel version answer different questions.
Update downloads at their source
For upstream installations, move pip to 26.2.2 or later, certifi users to 2026.10.19 or later, and uv’s bundled-root users to 0.13.4 or later. Pip 26.2.2 requires Python 3.10 or newer; update an older interpreter or obtain the applicable distributor fix. StepSecurity also identifies sigstore 4.5.1, conda 26.9.4 and Pixi 0.82.1 as remediation targets for environments using those tools. Check distributor backports and custom stores with the selected verifier against the affected chains.
Replace pinned CI and container base images that seed old Python tools, rebuild the image and record its resulting digest. Inspect build and runtime stages, cached virtual environments and independently installed uv binaries. Upgrade the parent interpreter or make a securely obtained corrected pip wheel an explicit bootstrap step before a new environment downloads dependencies; StepSecurity supplies a SHA-256-pinned upstream wheel procedure. Keep TLS verification enabled. An internal index that stops working after the CA change needs a replacement certificate chain.
Test certificate rejection with the actual pip, uv or application verifier and its chosen store against the disclosure’s affected chains, including alternate paths. The expected result is rejection of those chains while normal authorized package downloads still succeed. StepSecurity’s isolated corrected bundles rejected all fourteen published paths; a browser or unrelated curl success checks a different verifier. The durable change is the rebuilt job using a corrected downloader and the trust store you just tested.
