Safeguard
Supply Chain Security•

eMudhra CA Key Compromise Explained: Weak Keys, Not a Data Breach

Eight eMudhra intermediate CA keys were so weak anyone could compute them. Browsers blocked them fast; servers, containers and devices still need updates.

Safeguard Security Team
31 min read

The eMudhra incident is not a data breach. Eight intermediate CA private keys were generated so weakly that anyone could compute them from public certificates; one was the number 4. Browsers blocked them within hours. The remaining risk sits in servers, containers and devices with their own CA bundles, which need updates, rebuilds and a real test.

What happened

eMudhra is an Indian certificate authority that also runs a Global TLS business issuing website certificates. In April 2025 it created a set of intermediate CA certificates under its G3 hierarchy. The TLS intermediates were issued by emSign Root TLS CA G3, which browsers trusted through a cross-certificate from its publicly trusted ECC root, the emSign ECC Root CA G3. The code-signing pair was issued by emSign Root CS CA G3. Eight of those intermediates (six for TLS, two for code signing) ended up with private keys that were tiny integers instead of large random numbers.

On 17 October 2026 a researcher, credited by Mozilla only as Wayne and by Google as "a security researcher," reported this to the browser root programs with proof that he held the keys. Mozilla says it recovered the keys independently the same day. Scott Helme later published the recovered values: one key is 4, and the others are 56, 66, 115, 155, 156, 230 and 237.

Nobody had to break into anything. As The Hacker News noted in a correction on 21 October, the keys were not stolen; they could simply be calculated from the certificates. eMudhra told PSU Watch there was no unauthorised access to its infrastructure and no breach of customer data.

Date (UTC)EventSource
30 Apr 2025Key generation ceremony creates the eight intermediateseMudhra, via Mozilla Bugzilla and The Hacker News
14 May 2025Sectigo cross-signs the intermediates under AAA Certificate ServicesScott Helme; date from the certificates on the tracking site
17 Oct 2026, 18:05Chrome Root Program receives the reportGoogle
17 Oct, 19:45Chrome pushes a CRLSet block for the six TLS intermediates, matched by public keyGoogle
17 Oct, 20:06Mozilla receives the reportMozilla
17 Oct, 22:59OneCRL block reaches Firefox installs with standard settingsMozilla
18 Oct, 09:24 to 09:38eMudhra revokes all eight with reason caCompromiseMozilla Bugzilla, CERT-In
19 OctApple blocks the certificates; Android gets a block through Google Play Services around 22:00; Cloudflare learns of the issue around 17:00; the eight Sectigo cross-certificates show as revoked from 10:35Google, Cloudflare, Dennis Jackson's tracking site
20 OctMicrosoft blocks the certificates; Mozilla publishes its post, ships Firefox 158.0.1, ESR 115.43.1 and 153.5.1, and NSS 3.131.1 without the G3 ECC root; Go ships 1.27.3 and 1.26.10; Cloudflare ships cloudflared 2026.10.2The Hacker News, LWN, Mozilla, Cloudflare
21 OctCERT-In issues advisory CIAD-2026-0050; eMudhra files a statement with BSECERT-In, The Hacker News
27 Oct (expected)Chrome removes the G3 ECC root from the Chrome Root StoreGoogle

Two counts circulate. Google's post talks about eight subordinate CAs but says six intermediates had no certificates in Certificate Transparency (CT). The difference is the two code-signing intermediates, which Chrome's TLS verifier will not build a path through, according to The Hacker News.

The eight certificates and their keys, in detail

These keys are already public, and Chrome, Firefox, Android, Apple and Microsoft all distrust the certificates that hold them. We list the values so administrators can block and detect them in their own systems. They are of no use against a client that has been updated.

Every certificate value below comes from the data files on the tracking site run by Mozilla's Dennis Jackson (impacted-intermediates.json, roots.json and chains.zip). The serials and fingerprints match those listed in Mozilla Bugzilla 2083449, and the crt.sh entry for EM DV TLS CA - G3B shows the same serial, dates and hashes. We also recomputed each certificate hash and public key hash from the PEM files on the tracking site, and all of them matched.

Each of the eight keys sits in two certificates: one issued by eMudhra and one cross-certificate issued by Sectigo's AAA Certificate Services. Both copies hold the same public key, so they share one SPKI hash (the SHA-256 of the public key). That is why Google's CRLSet block matches on the public key rather than on a single certificate.

The eMudhra-issued certificates

All eight use an ECDSA key on the P-384 curve (secp384r1), are signed with ecdsa-with-SHA384, are CA certificates limited to issuing end-entity certificates, and were revoked by eMudhra with reason caCompromise on 18 October 2026 between 09:24 and 09:38 UTC. The G3B certificates name eMudhra BV in the Netherlands as the subject organisation; the G3C certificates name eMudhra Inc in the United States. The six TLS intermediates carry both the TLS server and TLS client authentication usages. Times are UTC.

Subject common namePurposeIssued byKeySerialNot BeforeNot AfterCertificate SHA-256SPKI SHA-256
EM DV TLS CA - G3BTLS server auth (DV)emSign Root TLS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-384A4AEE678F23362B4C0E460B772F21430 Apr 2025 15:54:0828 Apr 2040 18:30:0042C4ACCD12C4F59597925E1A08A7A90102608543809308D50EC427E118BA1493EBED6475C2C2D80FCB199F3FE8DD6E6B3CE60B77EB15D4E42C3DEC0C6F5B5105
EM OV TLS CA - G3BTLS server auth (OV)emSign Root TLS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-3846CADA367FB1C100088120EA202D56830 Apr 2025 16:00:1228 Apr 2040 18:30:0098B896625C0C230ADEEC3EB2CF6AAD5001ECF9156A68644E82374CE5833BC25B43BFFA19D6EF651451F6841E019931E96F6F2EAEFF28AB4B6F1CE4576DE2717B
EM EV TLS CA - G3BTLS server auth (EV)emSign Root TLS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-384C7C41EFE92D825F05EAE841A4A82C130 Apr 2025 16:03:3128 Apr 2040 18:30:00E7568FE6E12331F4FD7DE61DA4C7559D0F8EB192A218D4741A3BA75184333838E0254C7FCDC265E2F0F8A428DABB75AB4AE039B4872D62F5EE57F0877D5A8A41
EM DV TLS CA - G3CTLS server auth (DV)emSign Root TLS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-384588B2E3C2BB8CDA13E1A120925432130 Apr 2025 15:35:0928 Apr 2040 18:30:000164D7CEAE5BB909C272AF151FF44B1177AE9B47D9424B94F1D9558C30934D1949DD353DC2B919A3770645117D0E60C16115E7D1BC259EEFE734B00EA434FE5F
EM OV TLS CA - G3CTLS server auth (OV)emSign Root TLS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-384296926C227A3A1526392B19482A50430 Apr 2025 15:37:4128 Apr 2040 18:30:00CB6E15165AC802E9B3F993F16C25D41F4E81C21EBDE71AE1B012AC00BF9C7C3F63ECEFEE431D49523BC1136C4E72D0206A477086CAF606CD5CF025686C109CF8
EM EV TLS CA - G3CTLS server auth (EV)emSign Root TLS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-3848009928A64107601AF05FA2F19F10930 Apr 2025 15:39:3128 Apr 2040 18:30:00432EC25F0D28DE9006D97BF752F17BBB2CD41F669933FCB072D9A1148D0261F35C0660A2B164910D8FF589C18E14552E9E0EC237DCEFE2CB736D41A4811F81A0
EM OV CS CA - G3BCode signingemSign Root CS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-3847818933F8F85B4619A2B35FBA83D0A30 Apr 2025 16:08:2728 Apr 2040 18:30:009E39DE2881273ACC225A149C72BA3E0F51424963669AB633EE1DC7DF5DB067B4EC4FFA1AD0AC88081314B7AAFFEF6A91F97CD57291BB5BA686C5415F5EB4F6B6
EM OV CS CA - G3CCode signingemSign Root CS CA - G3; also cross-signed by AAA Certificate ServicesECDSA P-384544B7F922C31AE220A4A922916F6E630 Apr 2025 16:38:4028 Apr 2040 18:30:004B2460A466F95FD40113BCDCCA2CEB29B3B093921DE45474DA7DF48874C630B192C063D67E8F14DB71D288E11266FFDAF69CBF115F7BAB14F3BC2F68D25E0E30

Serials are written as the tracking site and Bugzilla give them. crt.sh shows the same numbers with a leading 00 byte, which is how the certificate encodes a positive serial.

How the issuing roots fit, according to the tracking site's roots.json and chain files:

  • emSign Root TLS CA - G3 (SHA-256 7DD78D5F4F13459A83DFF9ABBBA62EDBAF6F2D102BF257FD712F4D9F2746ED8D) and emSign Root CS CA - G3 (SHA-256 F2EDAAFF3D9B701FB4D14C9F285F8C0BAD90FC3BCC1FA07D47F4718EDABA34A5) are listed as included in Microsoft's root store only.
  • Other platforms reached the TLS intermediates through a cross-certificate that makes emSign Root TLS CA - G3 a child of emSign ECC Root CA - G3. That cross-certificate has SHA-256 3094025792039A68AF6E553686410BDAB7C0D4A36B9084CBA64202E35D6EBBDD and is valid from 11 July 2024 to 9 July 2039. The test host chains on the tracking site use exactly this path.
  • emSign ECC Root CA - G3 itself has SHA-256 86A1ECBA089C4A8D3BBE2734C612BA341D813E043CF9E8A862CD5C57A36BBE6B. This is the root Mozilla dropped in NSS 3.131.1 and Chrome removes on 27 October.
  • AAA Certificate Services (SHA-256 D7A7A0FB5D7E2731D771E9484EBCDEF71D5F0C3E0A2948782BC83EE0EA699EF4, valid to 31 December 2028) is shown as still included by Apple and Microsoft and already removed by Chrome and Mozilla.

The Sectigo cross-certificates

These hold the same eight keys, so the SPKI hashes are the ones in the table above. All eight were signed by AAA Certificate Services with sha256WithRSAEncryption, are valid from 14 May 2025 00:00:00 to 31 December 2028 23:59:59 UTC, and show as revoked with reason caCompromise on 19 October 2026 at 10:35:36 UTC in the tracking site's data. Bugzilla records Sectigo reporting the revocations complete around 20 October.

Subject common namePurposeSerialCertificate SHA-256
EM DV TLS CA - G3BTLS server auth (DV)A024FDF4BA665C785CE4A020483858B745A883F349AEDFD5F3A649B5498FFB121712BA8B448F3F2A91DBC5A766FCDDBE
EM OV TLS CA - G3BTLS server auth (OV)E94223BDE92F914E5AB9ACABFDAC37105F1DED4DD590AF74631290CF073B122A2AAC6A1FA479778A0BD43579BD832699
EM EV TLS CA - G3BTLS server auth (EV)D8F8685E4F2BD9D82402A85A1C1EB731579480AEA166290BD3C643589E795FC0D0E54E86505D180F1DFF99EFD3199512
EM DV TLS CA - G3CTLS server auth (DV)91F347F1A5B7D39962B95E0EE4E299D162B7F9868263F72F6911FC78CEAF72C1979158B7368BF648683BB2AA39B02E72
EM OV TLS CA - G3CTLS server auth (OV)8D5A4811939EF447D77111CDD9849AE97485B51C0ED192878FA1D2F948FB529AE1842CC5086C4B67F7BE5B2039DE9489
EM EV TLS CA - G3CTLS server auth (EV)05F078752DECE7A1BB8595D303167171FD9D5C2DBBD4995AB69B8D50C439D9527B00529199C2FD01B2174EB58F07021F
EM OV CS CA - G3BCode signing41E32B73AC185D6CE0D7480BACF84E69A496E23AC0CAB8155FC9B117B97EAE368EFCBB9041AEC8804D5A308D2D01C2D8
EM OV CS CA - G3CCode signingD6A5EF613B390F32EF9CDF349F77284184112972B8E59D14560AE7E7119654474AAD119990CF3722BFC1E3B91615E1FD

The private keys as published by researchers

Scott Helme's post maps each recovered private value to its certificate. Each value is the whole private key for both copies of that certificate.

CertificatePurposePrivate key value (decimal), as published by Scott Helme
EM DV TLS CA - G3BTLS156
EM OV TLS CA - G3BTLS155
EM EV TLS CA - G3BTLS115
EM DV TLS CA - G3CTLS230
EM OV TLS CA - G3CTLS4
EM EV TLS CA - G3CTLS56
EM OV CS CA - G3BCode signing66
EM OV CS CA - G3CCode signing237

Credit is reported differently by source. The Register says Helme recovered 4, 56 and 115 and that other researchers, not named, reported 66, 155, 156, 230 and 237; it does not map them to certificates. Helme's own post lists all eight with the mapping above. Mozilla says it recovered the keys independently on 17 October, and its bug report describes all eight as P-384 values below 256 without publishing them. The tracking site does not publish the values either. Its proof.zip holds the reporter's proof instead: a short message signed with each of the eight keys, which anyone can check against the public keys.

Why a P-384 key that equals a small number is broken

The public key in each certificate is a point on the curve. It is made by taking the curve's fixed, published base point and multiplying it by the private number. With a proper key, that number is chosen at random from a range about 384 bits wide, so there is nothing to search.

Here the private number was below 256. So anyone could take the base point, multiply it by 1, 2, 3 and onward up to 255, and compare each result with the public key printed in the certificate. One of them matches, and that number is the private key. That is at most 255 cheap calculations, which is why Helme reports recovering all eight in under a second. P-384 itself is not weakened. The curve only protects a key that was chosen from its full range.

How to use these values

  • Block by SPKI where your tools allow it. One SPKI hash covers both the eMudhra copy and the Sectigo copy of a key. Chrome's CRLSet already blocks this way, and Firefox, Apple, Android and Microsoft have shipped their own blocks.
  • Update trust stores rather than hand-editing them where you can. OpenSSL-based clients (curl, Python, Node, many appliances) and Java trust whatever is in their bundle or keystore. Update ca-certificates, certifi or the JDK, then confirm that emSign ECC Root CA - G3, emSign Root TLS CA - G3 and emSign Root CS CA - G3 are absent. In a Java keystore you can remove a leftover entry with keytool -delete and its alias.
  • Windows machines that miss Microsoft's updates. The tracking site offers Block-EmudhraCompromisedCA.ps1, which imports all 16 certificates into the LocalMachine Disallowed store. It covers Windows TLS and Authenticode checks, not applications with their own bundles, and the site asks users of managed devices to talk to IT first.
  • Search your inventories. Look for the 16 certificate hashes and 8 SPKI hashes in TLS scan results, certificate inventories, load balancer and proxy configs, stored chain files and container images. Any hit is a chain to replace.
  • Search CT. crt.sh accepts a certificate SHA-256 as a search term, as in the crt.sh entry for EM DV TLS CA G3B. Watch CT for your own domains too, as CERT-In recommends.
  • Alert on any chain containing them. Network sensors, TLS inspection proxies and SIEM rules that log certificate fingerprints can raise an alert whenever one of these hashes appears. For signed software, flag any binary whose signer chain includes either code-signing intermediate.

To compare a certificate you hold against the tables:

openssl x509 -in cert.pem -noout -fingerprint -sha256
openssl x509 -in cert.pem -noout -pubkey | openssl pkey -pubin -outform DER | openssl dgst -sha256

The first command prints the certificate hash with colons; remove them before comparing. The second prints the SPKI hash in lowercase.

Why a key like the number 4 matters

Elliptic curve keys work like this. The private key is a number. The public key is a fixed, publicly known starting point on the curve, combined with itself that many times. Going forward is cheap. Going backward, from public key to private key, is meant to be impractical.

That one-way property only holds when the private key is a huge random number. A P-384 key should be a random 384-bit value, which The Register puts at roughly 10 to the power of 115 possibilities. Mozilla's analysis found that all eight eMudhra keys were below 256. A laptop checks that many values in well under a second, which is what Helme reported.

So the question was never whether an attacker could get the keys. Anyone could. The real questions are whether anyone used them in the roughly 17 months Helme counts from April 2025 to October 2026, and which software would have believed a forged certificate.

With an intermediate CA key, someone can sign a certificate for any domain and most clients will accept it as long as they trust the chain. For the code-signing pair, CERT-In warns the risk is malware signed to look trusted.

On abuse, the evidence is reassuring but limited. Google says no TLS certificate chaining to the six web intermediates was logged in CT before the block, so forged certificates could not have worked against CT-enforcing clients such as Chrome. Cloudflare says it found no active exploitation on its services. CERT-In says public disclosures as of 21 October do not confirm malicious exploitation. Helme's caution still applies: for clients that never check CT, there is no way to be sure.

What eMudhra and CERT-In said

eMudhra's account, as reported by The Hacker News, PSU Watch, CERT-In and its comments on Mozilla's bug tracker, is preliminary. It says the keys came from a key generation ceremony on 30 April 2025 using FIPS 140-2 Level 3 hardware security modules. A wrap and unwrap step in that ceremony produced a second set of weak keys alongside the strong ones, and because the labels looked alike, the weak keys were used for the certificate signing requests. eMudhra says it is still establishing the root cause and re-checking its other ceremonies.

eMudhra also says:

  • Its root CA private keys and other intermediates are not affected.
  • Only one of the eight intermediates was in production, and none issued end-entity certificates.
  • It has stopped issuing under the G3 ECC root and is moving subscribers to its G1 RSA chain. On Bugzilla it estimated about 30,000 certificates need migration, mostly issued through ACME.
  • Global TLS is about 1% of its revenue.
  • Its Indian Digital Signature Certificate (DSC) and eSign services run on separate infrastructure and are unaffected.

CERT-In's advisory, CIAD-2026-0050, repeats that the domestic DSC and eSign services, regulated by the Controller of Certifying Authorities, are not affected. Some headlines summarised it as a warning about fake websites. That is a warning about what forged certificates could enable, such as impersonation of banking or payment sites, not a report of confirmed fake sites.

CERT-In's recommendations are practical. Users should update browsers and never click through certificate warnings. Administrators should confirm that affected chains are rejected, find services chaining to the affected intermediates or the G3 ECC root, replace certificates, watch CT logs for their domains, and check runtimes, container images, appliances and embedded devices that carry their own CA bundles. For background on CERT-In's role, see our guide to CERT-In directives.

Who is affected

SoftwareStatus as reportedWhat to do
Chrome desktopBlocked by CRLSet on 17 Oct, no restart needed (Google)Nothing beyond normal updates
FirefoxOneCRL block 17 Oct; 158.0.1 and ESR builds cover installs that block Remote Settings (Mozilla)Update if policy blocks Remote Settings
AndroidPlay Services block from 19 Oct; a restart applies it (Google)Restart devices
Apple platformsBlocked 19 Oct, but macOS /usr/bin/curl and /etc/ssl/cert.pem had not been updated (tracking site run by Mozilla's Dennis Jackson)See the tracking site's macOS steps
WindowsMicrosoft blocked 20 Oct (The Hacker News, LWN). Helme's tests found CryptoAPI accepted the chain unless revocation checking was onApply updates, then test
Linux and BSD bundlesUbuntu, Debian, Fedora, Arch, Alpine and Gentoo list fixed ca-certificates; FreeBSD now has advisory FreeBSD-SA-26:73.caroot (tracking site). BleepingComputer's earlier table still had Debian pendingUpdate the package and rebuild images
Python certifi2026.10.19 drops the G3 ECC rootUpdate lockfiles
Go1.27.3 and 1.26.10 reject the eight keysRebuild every Go binary
Node.jsSources disagree: the tracking site lists 22.23.4, 24.22.1 and 26.12.1; The Hacker News described a pending draft changeCheck the tracking site, then upgrade
JavaThe tracking site now lists OpenJDK and Oracle advisories with fixed builds, including 21.0.13.0.2, 17.0.21.0.2 and 8u511Upgrade each JDK, then inspect cacerts yourself
Rust, PHP, Elixir, Perlwebpki-roots 1.0.10, Composer ca-bundle 1.6.0 and 1.4.16, castore 1.0.22, Mozilla::CA 20261020Update dependencies
Appliances and IoTWhatever the firmware shipped. Helme notes device bundles could trust the chain until 2039; the cross-certificate to the G3 ECC root runs to 9 July 2039 and the intermediates themselves to 28 April 2040Ask vendors; restrict trust where you can

Site owners are affected differently. Google advises anyone holding a certificate that chains to the G3 ECC root to get a replacement from another hierarchy before Chrome's root removal on 27 October.

Why non-browser software is where the risk sits

Browsers recovered fast because they get pushed revocation updates (CRLSet, OneCRL) and enforce CT. Most other software has neither.

Helme lists curl, Python, Node, Go, Java, git and package managers as typical clients that trust a CA bundle on disk and do not check revocation or CT by default. In his tests, a forged certificate for a well-known API domain, served from a local machine, was accepted by default curl, Python and Node on every Linux and macOS system he tried. Revocation by eMudhra changes nothing for those clients. Only a new bundle or a new runtime does.

Cloudflare's post adds three points worth taping to the wall:

  1. Your SDK probably does not verify certificates itself. It hands that to an HTTP library, a language runtime, the operating system or a custom trust file, so an SDK update alone may change nothing.
  2. Patched packages can be indirect dependencies. Check the whole tree, rebuild images, then restart or redeploy.
  3. A browser test proves nothing about a background service, and a curl test proves nothing about an application that uses a different verifier.

Some places to look:

  • Container images. The bundle is frozen at build time. A host update does nothing for a running image. See our notes on container image supply chain incidents.
  • Language CA bundles. certifi, webpki-roots, Composer's ca-bundle and castore are dependencies pinned in lockfiles. They only move when you move them.
  • Java cacerts. Each JDK or JRE carries its own keystore, often several per host.
  • Go binaries. The fix lives in the standard library, so it takes a rebuild with a fixed toolchain, not a package update.
  • Mutual TLS. If a service accepts client certificates from any public CA, a forged client certificate could pass. LWN noted the client authentication usage on an affected intermediate; the certificates published on the tracking site show all six TLS intermediates, and their cross-certificates, carry it. Cloudflare tells mTLS users to review the CAs they trust.
  • Devices. Routers, printers and appliances update when their vendor ships firmware, if ever.

What to do now

  1. Check your OS trust bundle for the G3 ECC root. Fixed bundles drop it or block the intermediates. Use your distro's bundle path.
# Debian/Ubuntu/Alpine bundle; on RHEL use /etc/pki/tls/certs/ca-bundle.crt; macOS /etc/ssl/cert.pem
awk -v cmd='openssl x509 -noout -subject' '/BEGIN CERT/{close(cmd)};{print | cmd}' \
  < /etc/ssl/certs/ca-certificates.crt | grep "emSign ECC Root CA - G3"
dpkg -l ca-certificates    # Debian/Ubuntu
rpm -q ca-certificates     # Fedora/RHEL family
apk info -v ca-certificates  # Alpine

Other emSign roots, such as G1, are not part of the current removal, so match the G3 ECC name exactly. Compare package versions with the tracking site's table.

  1. Test the real client against the public test hosts. The tracking site run by Mozilla's Dennis Jackson hosts test endpoints served by the compromised chain. A certificate error is the result you want.
curl https://dv-g3b-emudhra.we-have-a-problem.com/
curl https://dv-g3b-aaa-emudhra.we-have-a-problem.com/
python3 -c "import requests; requests.get('https://dv-g3b-emudhra.we-have-a-problem.com/')"

Where you can, repeat the request through each application's own HTTP client.

  1. Check language bundles and runtimes.
pip show certifi                       # want 2026.10.19 or later
grep -c "emSign ECC Root CA - G3" "$(python3 -m certifi)"
keytool -list -cacerts -storepass changeit | grep -i emsign   # each JDK on the host
go version -m ./your-binary | head -1  # built with go1.27.3 or go1.26.10 or later?
node -v
  1. Rebuild and redeploy images. Pull fresh base images so the updated ca-certificates package lands, then roll the new images out.
docker build --pull --no-cache -t your-app:fixed .
docker run --rm your-app:fixed sh -c 'dpkg -l ca-certificates 2>/dev/null || apk info -v ca-certificates'
docker run --rm your-app:fixed curl -sS https://dv-g3b-emudhra.we-have-a-problem.com/   # expect an error
  1. Find out what your own services present. If you bought certificates from eMudhra, check whether they chain to the G3 ECC root and replace them before 27 October.
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | grep -E " s:| i:"
  1. Review mTLS trust. List the CA files your servers use to verify client certificates. Replace public bundles with your private CA.

  2. Never clear errors by turning verification off. Cloudflare calls it "important to not resolve these errors by disabling verification." If a legitimate partner breaks, it needs a new certificate.

What would have helped

Practices any team can use

Treat trust stores as dependencies. A CA bundle is code you ship. Keep an inventory of every place one lives: OS packages in each image, certifi and its peers in lockfiles, each JDK's cacerts, the Go toolchain version behind each binary. Then measure how long it takes to move all of them after an upstream change.

Make updates boring and fast. Automated dependency PRs for bundle packages, scheduled image rebuilds even when your code has not changed, and a quick redeploy path for trust store bumps.

Prefer clients that can receive revocation. Cloudflare says it backs projects such as upki, which treat a trust store as something updated quickly with revocation and CT data, not a static list. Where that is not possible, keep bundles current.

Keep mTLS trust narrow. Client authentication should trust your own CA, not the whole public web PKI.

Monitor CT for your domains. CERT-In recommends it. Helme's point stands that CT "detects mis-issuance though, it doesn't prevent it," so it complements trust updates rather than replacing them.

Key ceremony controls for anyone running a CA, including internal PKI. CERT-In's list is a good template: approved random number generators, proper HSM controls, independent checks of generated key parameters, key identifiers and CSR mappings, and maker and checker sign-off. A simple automated sanity check on every new public key, run by someone other than the ceremony team, catches a whole class of generation bugs. More on this in certificate authority compromise risks and what a certificate authority does.

Where Safeguard fits

Safeguard helps with the inventory and update half of this incident. It does not help with the CA half.

  • Finding every bundle you ship. SBOM and dependency scanning covers repos, container images and SBOM files: safeguard scan --dir ., safeguard scan --image <name> or safeguard scan --sbom <file>, with JSON results under ./output. The platform shows which projects contain a given component and version, so "which images still carry the old ca-certificates package" or "which services pin certifi below 2026.10.19" becomes a query rather than a week of grep. Our post on SBOM incident response walks through that workflow.
  • Matching advisories. Vulnerability matching against vulnerability databases picks up issues that have published identifiers. A bundle change with no advisory will not show as a vulnerability, so use the component and version view for those.
  • Keeping old versions out. Policies and gates evaluated in the platform can be used to hold back builds that still carry an outdated bundle version.
  • Making the change. Autonomous remediation can open fix PRs for dependency bumps; it ships off by default. The Safeguard CLI assistant can edit a Dockerfile or lockfile and run the rebuild with your approval of each command, and safeguard exec runs a single non-interactive assistant turn, which suits CI.

Where it does not help: Safeguard cannot see or improve a CA's key ceremony or HSM process, cannot tell you whether a forged certificate was ever used against you, and does not replace CT monitoring. It also will not reach trust stores on hosts, appliances or IoT firmware that you never scan. And no scanner would have prevented this incident; the keys were weak at the source.

Common mistakes

  • Calling it a breach. It was a key generation defect. Getting this right matters for how you brief leadership and customers.
  • Testing in a browser and stopping there. Browsers were fixed first. Your API clients were not.
  • Updating the host and forgetting the images. Containers keep the bundle they were built with.
  • Forgetting Go binaries. They need a rebuild with a fixed toolchain.
  • Removing roots without checking dependents. Mozilla warned that removing roots cuts off legitimate certificates too, so find your eMudhra-issued certificates first.
  • Disabling verification to clear errors. That turns a contained problem into an open one.

FAQ

Was eMudhra hacked?

No breach has been reported. eMudhra says there was no unauthorised access and no customer data breach. The problem is that eight keys were generated weakly in April 2025, so anyone could compute them from public certificates. That is why they were treated as compromised and revoked.

Did anyone forge certificates with these keys?

No abuse has been reported. Google found no TLS certificates from the six web intermediates in CT before its block, and Cloudflare and CERT-In report no confirmed exploitation. Clients that never check CT cannot rule it out, which is why updates matter.

Are Indian DSC and eSign certificates affected?

According to eMudhra and CERT-In, no. Those services run on separate infrastructure regulated by the Controller of Certifying Authorities. The affected intermediates belong to eMudhra's Global TLS business.

Why do some reports say six intermediates and others eight?

Eight intermediates had weak keys: six for TLS and two for code signing. Browser statements focus on the six TLS ones, because web browsers do not trust the code-signing pair for websites. Count certificates instead of keys and you get 16, because each key also sits in a Sectigo cross-certificate.

My website uses an eMudhra certificate. What should I do?

Check whether it chains to the G3 ECC root. If it does, Google advises installing a certificate from another hierarchy before Chrome removes that root, expected on 27 October. eMudhra says it is helping subscribers migrate.

If I only use browsers, am I safe?

Keep them updated and you are covered for browsing. Chrome, Firefox, Android, Apple and Microsoft have all shipped blocks. The work is in servers, scripts, CI jobs, containers and devices.

Fix it without waiting for upstream

In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

Try it yourself

Watch the Safeguard CLI handle a dependency fix end to end, asking before each command it runs.

Click through it at your own pace, or open it full screen.

See how to set up the local runner on your own machine and scan from the terminal.

Click through it at your own pace, or open it full screen.

To find every image and service that still ships an old CA bundle, download Safeguard and follow the CLI docs. For the wider month, see October 2026 security incidents and what would have helped.

Quick check

Why did browsers recover within hours while servers may still trust the eMudhra intermediates?

Browsers receive pushed revocation lists (CRLSet, OneCRL) and enforce Certificate Transparency. Most server software trusts a CA bundle on disk and does not check revocation, so it keeps trusting the chain until its bundle or runtime is updated and the service is rebuilt or restarted.

Your Python service passes the test, but runs in a container built two weeks ago. Are you done?

No. The container carries the CA bundle and certifi version it was built with. Update certifi, pull a fresh base image, rebuild, redeploy, then rerun the test from inside the running container.

Sources

Last reviewed: 22 October 2026. This is a developing story; check the linked advisories for the latest status.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.