eMudhra CA compromise: what servers and images still trust

eMudhra CA compromise: Chrome and Firefox blocked the keys on 17 October 2026; servers, runtimes and images trust them until rebuilt. What to check, by when.

The eMudhra CA compromise was reported on 17 October 2026, when a researcher showed the browser root programmes that the private keys of eight eMudhra intermediate certificate authorities could be recovered from their public certificates; six of them are TLS intermediates that Chrome, Firefox, Windows and Apple devices trusted. Chrome and Firefox blocked them that evening, Apple on 19 October and Microsoft on 20 October, each by pushing a block list to devices. Servers and containers trust the CA files they carry: until the ca-certificates package, the runtime and the image are updated and redeployed, they can still accept a certificate forged with these keys, and an end-of-life runtime gets no fix of its own.

This post covers the facts, how fast each trust store moved, where servers keep theirs, how to test, and a dated plan.

What happened to the eMudhra intermediate certificates?

eMudhra, a certificate authority based in Bengaluru, created the eight intermediates on 30 April 2025: six for TLS and two for code signing. Sectigo cross-signed them from its AAA Certificate Services root in May 2025, so each key sits in two certificates. Mozilla’s incident record says the eight P-384 private keys “all used integers less than 256”, where each should be a random 384-bit number. Scott Helme recovered every key from its public certificate in under a second.

Anyone holding one of the six TLS keys can issue a certificate for any domain. Using one against a client also requires a position on the network path between client and server, as Red Hat’s bulletin notes.

eMudhra revoked all eight on 18 October, and Sectigo its cross-signs on 19 October. In a statement of 26 October, its leadership wrote: “The flaw was ours. A script error resulted in issuing CA’s with weak keys.” eMudhra says that, based on its investigation to date, the intermediates had not issued publicly trusted end-entity certificates, and that its infrastructure and customer data were not compromised. Whether anyone used the keys before 17 October is not known. The Chrome Root Program says no TLS certificate under these intermediates was logged to Certificate Transparency (CT) before its block, so CT-enforcing browsers were not exposed by default. Many other clients do not check CT, and the disclosure site says: “We do not know if attackers exploited the flawed key generation to target these clients.” Since 22 October, mitmproxy 12.3 can sign test certificates with one of the keys (--emudhra): for anyone on the network path, intercepting an unpatched client is now a command-line option.

How fast did browsers and operating systems block the eMudhra intermediates?

Date (2026) Who What changed
17 October, 19:45 UTC Chrome CRLSet blocks the six TLS keys, cross-signs included
17 October, 22:59 UTC Firefox OneCRL blocks the certificates
19 October Apple Blocks the 12 TLS certificates; the root follows on 23 October
20 October Microsoft Windows Disallowed list blocks the intermediates; an out-of-band update of 26 October removes seven certificates from the Windows trust list
20 October Debian, Ubuntu, Alpine ca-certificates security updates (DSA 6572-1, DLA 4845-1, Ubuntu, Alpine)
21 October Node.js 22.23.4, 24.22.1 and 26.12.1 ship Mozilla’s updated roots
22 and 23 October Red Hat ca-certificates for RHEL 7 ELS to 10 (RHSB-2026-012)
25 October Python 3.11.18, 3.12.16, 3.13.18, 3.14.10, 3.15.2 add a denylist to ssl

Helme lists curl, Python, Node, Go and Java among clients that “trust a CA bundle on disk, they don’t check revocation by default, and they don’t check CT”, so eMudhra’s revocation does not protect them. The packages and releases above do, once installed on a machine or rebuilt into an image.

Does updating ca-certificates fix containers and runtimes?

Only for what reads the system store. A server or an image usually holds several copies of trust, and each updates on its own:

Layer Where it reads trusted roots What refreshes it
Operating system The ca-certificates package (/etc/ssl/certs on Debian, Ubuntu, Alpine; /etc/pki/ca-trust on RHEL) The security update, then a restart of long-running services
Container image A copy of that package as it was at build time A rebuild from the updated base, without cached layers, and a redeploy
Python ssl: OpenSSL’s default paths (the system store on Linux); requests and pip: certifi certifi 2026.10.19 and pip 26.2.2 in every environment; a fixed Python
Node.js A snapshot of Mozilla’s store inside the binary Node.js 22.23.4, 24.22.1 or 26.12.1
Go The system store on most platforms; in a scratch image, the CA file copied in at build time The system update or a rebuilt image; Go 1.26.10 or 1.27.3 for the denylist
Java Standalone JDK: lib/security/cacerts (jre/lib/security/cacerts on JDK 8); Debian and Ubuntu OpenJDK: /etc/ssl/certs/java/cacerts A vendor build that fixes JDK-8395690; on Debian and Ubuntu, a rebuilt keystore

Your images inherit the fix only when rebuilt, and the Python Software Foundation asks for rebuilds “with layer caching disabled”, so that a cached apt-get install ca-certificates layer does not survive.

Python has two stores. In the PSF’s guidance thread, a CPython core developer warns that “pip always loads the CA certificates from its vendored certifi in addition to the system trust store”, so any pip older than 26.2.2 “will keep trusting the compromised intermediate CAs regardless of the system trust store”. Since 25 October, fixed Python releases block the keys in ssl, protecting normal pip use before pip is upgraded.

Which runtimes still trust the eMudhra intermediates?

As of 27 October 2026, these lines get no fix from their own projects, because their support has ended:

  • Python 3.10 and older. End of life since 1 October 2026; the PSF says they are “no longer eligible for security fixes”. On a Linux distribution, ssl still follows the updated system store; an old certifi or pip does not.
  • Node.js 20 and older. Node.js 20 reached end of life on 30 April 2026, and its embedded store keeps the root it shipped with.
  • Go 1.25 and older. No denylist. On Linux they read the system store; a scratch image with an old CA file stays exposed.
  • Debian 11 (bullseye) base images. Debian’s LTS for bullseye ended on 31 August 2026, and the advisories of 20 October cover Debian 13 and 12.

Older Ubuntu releases get the update only through Ubuntu Pro (tracking bug).

Java was the open item on 27 October 2026: the OpenJDK project tells users of standalone runtimes to install a vendor build whose release notes list JDK-8395690, or meanwhile to delete the roots it lists from the runtime’s cacerts with keytool. OpenJDK from Debian or Ubuntu packages needs a manual step even after the update, because of a long-standing bug in ca-certificates-java: rm -f /etc/ssl/certs/java/cacerts, then update-ca-certificates --fresh.

On 24 October 2026, Amazon Corretto 21.0.13.0.11 and 17.0.21.0.11 and the matching 8, 11 and 25 builds fixed CVE-2026-114820, the CVE for JDK-8395690, and removed the four roots OpenJDK names. On 27 October, Adoptium said Eclipse Temurin 17.0.21+9, 21.0.13+9 and 25.0.5+8 follow Mozilla instead: they drop emSign ECC Root CA - G3 and AAA Certificate Services, which signed the compromised intermediates, but keep emSign Root CA - G1, which Mozilla still trusts; CheckCerts.java flags it, inappropriately in Adoptium’s view. On 5 November, Ubuntu’s USN-9001-1 fixed the keystore bug on Ubuntu 22.04, 24.04 and 26.04 LTS and 26.10; Debian and older Ubuntu releases have no fix in Launchpad bug 2061817, so the manual step still applies there.

Engineers’ Macs are the other gap. Apple’s block does not reach curl, git, python3 and the other command-line tools that read /etc/ssl/cert.pem, which Apple says “will be updated in a future macOS update”. A build started from a laptop can fetch dependencies through the old trust. When we checked again on 7 November 2026, Apple’s page, revised on 29 October, still said so; it now gives commands to remove emSign ECC Root CA - G3, and optionally AAA Certificate Services, from the file, and warns that other sites may then fail and that a macOS update can restore the file.

How do you check that a server rejects the eMudhra chains?

The disclosure site, published by Mozilla’s Dennis Jackson with community contributors, serves real chains through the compromised intermediates. Run these inside each host and each image that makes outbound TLS calls:

curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/

A certificate error is the result you want; the second host uses the Sectigo cross-sign. curl tests only the system store, so repeat with each runtime the image uses:

python3 -c "import urllib.request as u; u.urlopen('https://dv-g3b-emudhra.we-have-a-problem.com/')"
python3 -c "import requests; requests.get('https://dv-g3b-emudhra.we-have-a-problem.com/')"
node -e "fetch('https://dv-g3b-emudhra.we-have-a-problem.com/').then(() => console.log('TRUSTED'), (e) => console.log('rejected', e.cause?.code))"

Each should end in a certificate verification error; for Node, rejected followed by a certificate error code such as CERT_REVOKED or UNABLE_TO_GET_ISSUER_CERT_LOCALLY, not a network error such as ENOTFOUND. For Java, OpenJDK publishes CheckCerts.java. For machines without internet access, the site’s chains.zip holds every chain in PEM format, with OpenSSL instructions. Keep the output with the change record: it is the evidence that the fix reached that image.

What to do, and by when

The fixes were published between 17 October and 5 November 2026; Apple’s update for the macOS command-line tools was still pending on 7 November. No regulation sets a deadline, so every date below is our suggestion, counted from 27 October; only the end-of-life dates in step 7 are fixed.

  1. By 28 October 2026: update the system trust store on every machine. Install your distribution’s ca-certificates update, then restart long-running services, which may have loaded the old bundle at start.
  2. By 30 October 2026: rebuild and redeploy every image. Pull the updated base (docker build --pull --no-cache), include CI runners and build images, and redeploy.
  3. By 30 October 2026: update the stores runtimes carry. Move Node.js, Python, certifi and pip to the fixed releases above in every virtualenv, lock file and image, rebuild Go binaries with a fixed Go, and follow OpenJDK’s advice for Java.
  4. Before closing the change: prove that a bad chain fails in every image and runtime, and file the output. For entities under NIS2, it is evidence of the “vulnerability handling” Article 21(2)(e) requires.
  5. By 30 October 2026: check your own certificates. If a service you run presents an eMudhra certificate under a G3 root (emSign ECC Root CA - G3 in Mozilla’s store; six G3 roots and the AAA cross-sign on Windows), updated clients will reject it. Microsoft advises getting “replacement certificates or an alternative trusted chain”.
  6. By 6 November 2026: reach what automatic updates miss. Microsoft asks administrators to check disconnected Windows devices; air-gapped Linux hosts need the package through your transfer process; appliances need vendor firmware.
  7. By 31 December 2026: retire end-of-life runtimes and bases: Python 3.10, Node.js 20, Go 1.25 and Debian 11 images. Their end dates have passed; the deadline is ours.
  8. At the next policy review: write down a rebuild rule. For example, every image rebuilt at least weekly and within two working days of a trust store or runtime security release, with a pipeline test that fails when a known-bad chain verifies. Ask your suppliers the same, alongside our CRA supplier questions.

The fixes were public. Someone still has to rebuild

Most of this response can be read in public: the incident record with UTC timestamps, a proof of key control anyone can check with OpenSSL, Debian’s changelog, Node’s pull request with its design and known limitation. With open source, the fix is public and anyone can apply it: the fixed packages were in the Debian, Ubuntu and Alpine archives on 20 October, three days after the report, and anyone could rebuild that day.

What open source does not give you is someone who rebuilds your images. PHP2Shell taught the same lesson for a runtime flaw, and the practice that closes the gap is the same:

  • An inventory of where trust lives in each image: system package, runtime, certifi, cacerts.
  • Rebuilds on a schedule and on events, from current bases, without cached layers.
  • Supported runtimes only, each with its end-of-life date on file.
  • A test that a known-bad chain fails, run in the pipeline and kept as evidence.

How Pilae fits

Most of this fix reached servers as an operating system update; the rest depends on knowing what runs where, and who approves each change. Pilae operates open-source apps on your premises or on dedicated machines in Pilae Cloud. On premises, Pilae runs everything from the operating system up; in Pilae Cloud, the whole stack.

  • Hardened machines with automatic security updates. Every machine runs a minimal operating system with automatic security updates for the base system, the channel through which Debian, Ubuntu and Red Hat shipped this fix.
  • Every app and machine on one screen. The console shows each app’s version, machine and health, each machine’s operating system, and pending updates and advisories next to the app they affect.
  • Fixes planned with a rollback. Upstream advisories for every app you run are tracked against your versions. The Pilae Agent plans each fix with a verified backup and a rollback; after your approval it is applied in your agreed window, or at once if you approve an emergency change.
  • Checked and recorded. Probes check every 60 seconds that each app answers and that its certificate is valid, and every fix is written to the audit log, exportable to your SIEM.
  • Disconnected sites and roles in writing. On air-gapped sites, each release and security fix is signed and passed through your transfer process on the agreed schedule. Under managed operations, the responsibility matrix puts the operating system and security fixes on Pilae’s side and approvals on yours.

Who updates which layer, and how fast, is better settled in writing before the next CA incident than during it. To find out where trust lives in your estate, talk to an engineer: we go through the apps you run, the images and runtimes under them, and who is responsible for each layer.

Tell us what you need to run.

Thirty minutes with an engineer, a written plan and a fixed price for the first workload.