Compromised intermediate keys threaten Python dependency downloads when a client trusts the affected chain. Update the downloader, its CA bundle, and the interpreter that seeds new environments.2026-10-22T22:38:11.239Z4 min2026appsec
4 min read

eMudhra CA Compromise Prompts pip and uv Trust Updates

Compromised intermediate keys threaten Python dependency downloads when a client trusts the affected chain. Update the downloader, its CA bundle, and the interpreter that seeds new environments.

By
Show the 1-minute readHide the 1-minute read

Compromised eMudhra intermediate CA keys can let someone who intercepts a connection impersonate an HTTPS package index to a Python downloader that still trusts the affected chain. StepSecurity tested fourteen published certificate chains: an old certifi bundle accepted seven, while corrected certifi and pip bundles rejected all fourteen. StepSecurity says whether attackers exploited this weakness against non-browser clients remains unknown. Use the test result to scope outdated client trust; investigate suspicious downloaded artifacts separately. Browser blocks leave pip’s and uv’s independent roots to update.

Inventory the interpreters and downloaders in virtual environments, self-hosted CI runners, build stages and application images. Run python -m pip --version, python -m pip show certifi and python -c "import ensurepip; print(ensurepip.version())" with the interpreter that creates new environments. Update upstream pip to 26.2.2 or later, certifi to 2026.10.19 or later and uv’s bundled-root installations to 0.13.4 or later. Pip 26.2.2 needs Python 3.10 or newer; older interpreters need an upgrade or distributor fix. Check PIP_CERT, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, SSL_CERT_FILE and SSL_CERT_DIR for custom trust, and replace affected CI base images and pinned build layers.

Test the workload’s selected verifier against the affected chains and confirm rejection, including alternate paths. Then confirm authorized package downloads still work through the replacement trust chain. Treat unexpected artifacts or processes as an investigation lead distinct from an outdated CA bundle.

A fractured certificate-chain seal on a blank certificate framed by blue and yellow Python-shaped enamel.

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.

Primary sources

Continue reading

Article figurePinch or double-tap to zoom, then drag to pan.