Meet the new Cycode > now you're in command.

Read the blog

Blog

eMudhra intermediate CA compromise: What to patch and how to find it

7 MIN

eMudhra Intermediate CA Compromise: What to Patch and How to Find It

Eight eMudhra intermediate CAs were generated with private keys so small that anyone can compute them from the public certificate. Chrome and Firefox blocked them within hours, Microsoft followed on Oct 20 and Apple on Oct 22. Container images, language runtimes and custom CA bundles will keep trusting them until someone rebuilds or updates them, and that is where most teams are still exposed.

What Happened

In one key ceremony eMudhra generated 24 intermediate CAs. For 8 of them the P-384 private key was an integer below 256. Six are TLS intermediates (EM DV, OV and EV TLS CA, G3B and G3C) and two sign code (EM OV CS CA G3B and G3C). Sectigo had cross-signed all 8 under its AAA Certificate Services root, so 16 certificates are affected. eMudhra says a key-ceremony script created a second, weak keypair with a similar label and the weak key was used for the CSR. Root program participants have questioned that explanation and the investigation is still open.

Date Event
Apr 30, 2025 The 24 intermediates are generated.
Oct 17, 2026 A researcher reports with signed proof. Firefox and Chrome block the certificates the same day.
Oct 18, 2026 eMudhra revokes the 8 intermediates as compromised.
Oct 19, 2026 Downstream trust stores are notified and Sectigo revokes its cross-signs. OS vendors, runtimes and libraries start shipping fixed trust stores.
Oct 20, 2026 Microsoft blocks the certificates. Mozilla removes trust in the emSign ECC Root CA – G3 and eMudhra stops issuing under it. The public tracking page goes live.
Oct 22, 2026 Apple blocks the certificates.

Chrome’s removal of the emSign ECC Root CA – G3 takes effect on Oct 27. As of Oct 21, no exploitation had been reported.

Blog – PODCAST CTA – 1Blog – PODCAST CTA – 1Blog – PODCAST CTA – 1

Why Patching the OS Is Not Enough

No certificate issued by these intermediates appears in Certificate Transparency logs, so browsers that enforce CT could not have been attacked silently. curl and most language runtimes check neither CT nor revocation. Anyone holding one of the six TLS keys can issue a certificate for any host, and a client that still trusts the emSign ECC Root CA – G3 or AAA Certificate Services will accept it. The two code-signing keys could sign code that Windows trusted until Microsoft’s block on Oct 20.

The fix is an updated trust store, and many programs bring their own. Node.js ships its own root list. Java ships cacerts and its fix blocks the 16 intermediates (CVE-2026-91403). Upstream pip always loads its bundled certifi in addition to the system store, so a patched OS does not fix an old pip. Go and most Python builds on Linux read the OS store; Go 1.27.3 and 1.26.10 add a denylist in crypto/x509 (CVE-2026-111943) for systems whose store is stale. A container image keeps whatever ca-certificates package it was built with until it is rebuilt.

Where the Old Trust Lives

Location How it gets there Fixed in
ca-certificates in container images Frozen at build time Alpine 20261020-r0; Debian 20250419~deb12u2, 20250419+deb13u1, 20260816+nmu1; Ubuntu 20260816ubuntu0.22.04.1, 0.24.04.1, 0.26.04.1, 0.26.10.1; RHEL 8, 9, 10 2026.2.92_v9.0.319-81.3.el8_10, -90.3.el9_8, -100.3.el10_2 (RHEL 7 pending); Fedora 2026.2.92_v9.0.319; Chainguard 20260909-r3
Runtime base images Pinned to an old version, pinned by digest, or on an end-of-life line Node.js 26.12.1, 24.22.1, 22.23.4; Go 1.27.3, 1.26.10; Java 27.0.1.0.2, 25.0.5.0.2, 21.0.13.0.2, 17.0.21.0.2, 11.0.33.0.2, 8u511 b32; Python 3.15.1, 3.14.9, 3.13.17; Bun 1.4.4; Deno 2.9.8
Python environments Upstream pip’s bundled certifi, including pip installed by ensurepip in new virtual environments pip 26.2.2, certifi 2026.10.19
Custom CA bundles Files copied into images, or pointed to with SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, PIP_CERT or -Djavax.net.ssl.trustStore Never updated by the OS. Block the 16 intermediates where the client supports it, or remove the emSign and affected AAA entries. Pointing PIP_CERT at the OS store does not fix an old pip

Electron apps need 44.9.1, 43.8.1 or 42.11.16. Removing trust in AAA Certificate Services can break sites that still chain to it, so test before rolling out.

Blog – Demo CTA – 2Blog – Demo CTA – 2Blog – Demo CTA – 2

How Cycode Helps

Old trust can hide in these places. Cycode checks them with queries in the Context Intelligence Graph, and each result links to the repository it came from.

Area What to look for Fix
Dependencies Libraries that ship their own CA bundle below the fixed version: certifi < 2026.10.19, pip < 26.2.2, uv < 0.13.5, conda < 26.9.4, webpki-roots and webpki-root-certs < 1.0.10, rustls-webpki < 0.103.16, castore < 1.0.22, Erlang certifi < 2.18.0, Mozilla::CA < 20261020, cfssl trust store < 2026.10.1 Upgrade the dependency
Container images ca-certificates packages older than the fixed version for each distribution, and Node.js, Java, pip or certifi below the fixed versions Rebuild from a patched base image
Dockerfiles and IaC Base images below the fixed version, on an end-of-life line or pinned by digest. Dockerfiles and Kubernetes manifests that set a custom CA bundle Move the base image, remove or update the bundle
Your certificates Leaf certificates issued from eMudhra chains in repositories and IaC, such as Kubernetes TLS secrets and Terraform certificate resources Request new certificates
CI/CD Workflows using pypa/gh-action-pypi-publish < 1.14.3, and ArgoCD below 3.3.18, 3.4.12 or 3.5.6 Bump the action or tool version
Developer machines VS Code < 1.143.1, Claude Code < 2.1.303 and Git for Windows < 2.56.0.3 on machines with Cycode Workstation Protection Update the tool

Three of these are on the Threat Intelligence dashboard now. Each item shows how many of your assets match and opens the query behind it.

Images with unpatched ca-certificates. Container images whose ca-certificates package is older than the fixed version for its distribution: Alpine and Chainguard (apk), Debian and Ubuntu (deb), and RHEL and Fedora (rpm). Results show the image, its tags and the installed version.

Cycode query results listing container images with outdated ca-certificates packages, showing package version, package type, image, tags and digest

Images with outdated runtimes. Images with Node.js or Java runtimes, pip or certifi below the fixed versions. These keep their own trust data, so a patched base image alone does not fix them.

Container images with Go and Python runtimes below the fixed versions

Dockerfiles on unpatched base images. Dockerfiles that build on Node.js, Python, Go, Java, Bun or Deno images below the fixed version, on a line with no fixed release or pinned by digest. Floating tags such as node:22 are left out, because rebuilding with –pull picks up the fixed image once it is republished.

Dockerfiles on base images below the fixed version, with their repository

We tested each query against known-vulnerable and known-fixed Dockerfiles, manifests and image versions before release.

First 24 Hours

  1. Rebuild container images with docker build –pull –no-cache, so the base image and package layers refresh.
  2. Move runtimes and base images to the fixed versions above, and replace end-of-life lines.
  3. Upgrade pip to 26.2.2 and certifi to 2026.10.19 in every Python environment and image. The old pip downloads the new one, so install the pip wheel by hash as the Python advisory describes.
  4. Find custom CA bundles and trust stores. Block the 16 intermediates where the client supports it, or remove the emSign and affected AAA entries.
  5. From inside your containers and CI runners, connect to https://dv-g3b-emudhra.we-have-a-problem.com and https://dv-g3b-aaa-emudhra.we-have-a-problem.com. Each must fail with a certificate error, not a network error.
Blog – Demo CTA – 3Blog – Demo CTA – 3Blog – Demo CTA – 3

Sources