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) | Event | Source |
|---|---|---|
| 30 Apr 2025 | Key generation ceremony creates the eight intermediates | eMudhra, via Mozilla Bugzilla and The Hacker News |
| 14 May 2025 | Sectigo cross-signs the intermediates under AAA Certificate Services | Scott Helme; date from the certificates on the tracking site |
| 17 Oct 2026, 18:05 | Chrome Root Program receives the report | |
| 17 Oct, 19:45 | Chrome pushes a CRLSet block for the six TLS intermediates, matched by public key | |
| 17 Oct, 20:06 | Mozilla receives the report | Mozilla |
| 17 Oct, 22:59 | OneCRL block reaches Firefox installs with standard settings | Mozilla |
| 18 Oct, 09:24 to 09:38 | eMudhra revokes all eight with reason caCompromise | Mozilla Bugzilla, CERT-In |
| 19 Oct | Apple 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:35 | Google, Cloudflare, Dennis Jackson's tracking site |
| 20 Oct | Microsoft 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.2 | The Hacker News, LWN, Mozilla, Cloudflare |
| 21 Oct | CERT-In issues advisory CIAD-2026-0050; eMudhra files a statement with BSE | CERT-In, The Hacker News |
| 27 Oct (expected) | Chrome removes the G3 ECC root from the Chrome Root Store |
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 name | Purpose | Issued by | Key | Serial | Not Before | Not After | Certificate SHA-256 | SPKI SHA-256 |
|---|---|---|---|---|---|---|---|---|
EM DV TLS CA - G3B | TLS server auth (DV) | emSign Root TLS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | A4AEE678F23362B4C0E460B772F214 | 30 Apr 2025 15:54:08 | 28 Apr 2040 18:30:00 | 42C4ACCD12C4F59597925E1A08A7A90102608543809308D50EC427E118BA1493 | EBED6475C2C2D80FCB199F3FE8DD6E6B3CE60B77EB15D4E42C3DEC0C6F5B5105 |
EM OV TLS CA - G3B | TLS server auth (OV) | emSign Root TLS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | 6CADA367FB1C100088120EA202D568 | 30 Apr 2025 16:00:12 | 28 Apr 2040 18:30:00 | 98B896625C0C230ADEEC3EB2CF6AAD5001ECF9156A68644E82374CE5833BC25B | 43BFFA19D6EF651451F6841E019931E96F6F2EAEFF28AB4B6F1CE4576DE2717B |
EM EV TLS CA - G3B | TLS server auth (EV) | emSign Root TLS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | C7C41EFE92D825F05EAE841A4A82C1 | 30 Apr 2025 16:03:31 | 28 Apr 2040 18:30:00 | E7568FE6E12331F4FD7DE61DA4C7559D0F8EB192A218D4741A3BA75184333838 | E0254C7FCDC265E2F0F8A428DABB75AB4AE039B4872D62F5EE57F0877D5A8A41 |
EM DV TLS CA - G3C | TLS server auth (DV) | emSign Root TLS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | 588B2E3C2BB8CDA13E1A1209254321 | 30 Apr 2025 15:35:09 | 28 Apr 2040 18:30:00 | 0164D7CEAE5BB909C272AF151FF44B1177AE9B47D9424B94F1D9558C30934D19 | 49DD353DC2B919A3770645117D0E60C16115E7D1BC259EEFE734B00EA434FE5F |
EM OV TLS CA - G3C | TLS server auth (OV) | emSign Root TLS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | 296926C227A3A1526392B19482A504 | 30 Apr 2025 15:37:41 | 28 Apr 2040 18:30:00 | CB6E15165AC802E9B3F993F16C25D41F4E81C21EBDE71AE1B012AC00BF9C7C3F | 63ECEFEE431D49523BC1136C4E72D0206A477086CAF606CD5CF025686C109CF8 |
EM EV TLS CA - G3C | TLS server auth (EV) | emSign Root TLS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | 8009928A64107601AF05FA2F19F109 | 30 Apr 2025 15:39:31 | 28 Apr 2040 18:30:00 | 432EC25F0D28DE9006D97BF752F17BBB2CD41F669933FCB072D9A1148D0261F3 | 5C0660A2B164910D8FF589C18E14552E9E0EC237DCEFE2CB736D41A4811F81A0 |
EM OV CS CA - G3B | Code signing | emSign Root CS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | 7818933F8F85B4619A2B35FBA83D0A | 30 Apr 2025 16:08:27 | 28 Apr 2040 18:30:00 | 9E39DE2881273ACC225A149C72BA3E0F51424963669AB633EE1DC7DF5DB067B4 | EC4FFA1AD0AC88081314B7AAFFEF6A91F97CD57291BB5BA686C5415F5EB4F6B6 |
EM OV CS CA - G3C | Code signing | emSign Root CS CA - G3; also cross-signed by AAA Certificate Services | ECDSA P-384 | 544B7F922C31AE220A4A922916F6E6 | 30 Apr 2025 16:38:40 | 28 Apr 2040 18:30:00 | 4B2460A466F95FD40113BCDCCA2CEB29B3B093921DE45474DA7DF48874C630B1 | 92C063D67E8F14DB71D288E11266FFDAF69CBF115F7BAB14F3BC2F68D25E0E30 |
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-2567DD78D5F4F13459A83DFF9ABBBA62EDBAF6F2D102BF257FD712F4D9F2746ED8D) andemSign Root CS CA - G3(SHA-256F2EDAAFF3D9B701FB4D14C9F285F8C0BAD90FC3BCC1FA07D47F4718EDABA34A5) 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 - G3a child ofemSign ECC Root CA - G3. That cross-certificate has SHA-2563094025792039A68AF6E553686410BDAB7C0D4A36B9084CBA64202E35D6EBBDDand 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 - G3itself has SHA-25686A1ECBA089C4A8D3BBE2734C612BA341D813E043CF9E8A862CD5C57A36BBE6B. This is the root Mozilla dropped in NSS 3.131.1 and Chrome removes on 27 October.AAA Certificate Services(SHA-256D7A7A0FB5D7E2731D771E9484EBCDEF71D5F0C3E0A2948782BC83EE0EA699EF4, 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 name | Purpose | Serial | Certificate SHA-256 |
|---|---|---|---|
EM DV TLS CA - G3B | TLS server auth (DV) | A024FDF4BA665C785CE4A020483858B7 | 45A883F349AEDFD5F3A649B5498FFB121712BA8B448F3F2A91DBC5A766FCDDBE |
EM OV TLS CA - G3B | TLS server auth (OV) | E94223BDE92F914E5AB9ACABFDAC3710 | 5F1DED4DD590AF74631290CF073B122A2AAC6A1FA479778A0BD43579BD832699 |
EM EV TLS CA - G3B | TLS server auth (EV) | D8F8685E4F2BD9D82402A85A1C1EB731 | 579480AEA166290BD3C643589E795FC0D0E54E86505D180F1DFF99EFD3199512 |
EM DV TLS CA - G3C | TLS server auth (DV) | 91F347F1A5B7D39962B95E0EE4E299D1 | 62B7F9868263F72F6911FC78CEAF72C1979158B7368BF648683BB2AA39B02E72 |
EM OV TLS CA - G3C | TLS server auth (OV) | 8D5A4811939EF447D77111CDD9849AE9 | 7485B51C0ED192878FA1D2F948FB529AE1842CC5086C4B67F7BE5B2039DE9489 |
EM EV TLS CA - G3C | TLS server auth (EV) | 05F078752DECE7A1BB8595D303167171 | FD9D5C2DBBD4995AB69B8D50C439D9527B00529199C2FD01B2174EB58F07021F |
EM OV CS CA - G3B | Code signing | 41E32B73AC185D6CE0D7480BACF84E69 | A496E23AC0CAB8155FC9B117B97EAE368EFCBB9041AEC8804D5A308D2D01C2D8 |
EM OV CS CA - G3C | Code signing | D6A5EF613B390F32EF9CDF349F772841 | 84112972B8E59D14560AE7E7119654474AAD119990CF3722BFC1E3B91615E1FD |
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.
| Certificate | Purpose | Private key value (decimal), as published by Scott Helme |
|---|---|---|
EM DV TLS CA - G3B | TLS | 156 |
EM OV TLS CA - G3B | TLS | 155 |
EM EV TLS CA - G3B | TLS | 115 |
EM DV TLS CA - G3C | TLS | 230 |
EM OV TLS CA - G3C | TLS | 4 |
EM EV TLS CA - G3C | TLS | 56 |
EM OV CS CA - G3B | Code signing | 66 |
EM OV CS CA - G3C | Code signing | 237 |
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 - G3andemSign Root CS CA - G3are absent. In a Java keystore you can remove a leftover entry withkeytool -deleteand 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
| Software | Status as reported | What to do |
|---|---|---|
| Chrome desktop | Blocked by CRLSet on 17 Oct, no restart needed (Google) | Nothing beyond normal updates |
| Firefox | OneCRL block 17 Oct; 158.0.1 and ESR builds cover installs that block Remote Settings (Mozilla) | Update if policy blocks Remote Settings |
| Android | Play Services block from 19 Oct; a restart applies it (Google) | Restart devices |
| Apple platforms | Blocked 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 |
| Windows | Microsoft blocked 20 Oct (The Hacker News, LWN). Helme's tests found CryptoAPI accepted the chain unless revocation checking was on | Apply updates, then test |
| Linux and BSD bundles | Ubuntu, 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 pending | Update the package and rebuild images |
| Python certifi | 2026.10.19 drops the G3 ECC root | Update lockfiles |
| Go | 1.27.3 and 1.26.10 reject the eight keys | Rebuild every Go binary |
| Node.js | Sources disagree: the tracking site lists 22.23.4, 24.22.1 and 26.12.1; The Hacker News described a pending draft change | Check the tracking site, then upgrade |
| Java | The tracking site now lists OpenJDK and Oracle advisories with fixed builds, including 21.0.13.0.2, 17.0.21.0.2 and 8u511 | Upgrade each JDK, then inspect cacerts yourself |
| Rust, PHP, Elixir, Perl | webpki-roots 1.0.10, Composer ca-bundle 1.6.0 and 1.4.16, castore 1.0.22, Mozilla::CA 20261020 | Update dependencies |
| Appliances and IoT | Whatever 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 2040 | Ask 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:
- 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.
- Patched packages can be indirect dependencies. Check the whole tree, rebuild images, then restart or redeploy.
- 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
- 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.
- 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.
- 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
- 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
- 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:"
-
Review mTLS trust. List the CA files your servers use to verify client certificates. Replace public bundles with your private CA.
-
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>orsafeguard 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 execruns 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 situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull 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
- Cloudflare: eMudhra certificate compromise
- Google: Protecting Chrome and Android users from compromised eMudhra intermediate CA certificates
- Mozilla Security Blog: Protecting Firefox users following the compromise of eMudhra intermediate certificates
- Mozilla Bugzilla 2083449: eMudhra private key compromise of intermediate certificates
- eMudhra incident tracking and test site
- CERT-In advisory CIAD-2026-0050
- Scott Helme: Eight Bits of Trust
- The Register: eMudhra private keys compromised, one was the number 4
- BleepingComputer: Mozilla, Google, Apple block compromised eMudhra CA certificates
- The Hacker News: Eight eMudhra CA keys compromised
- LWN: eMudhra intermediate CA compromise
- PSU Watch: eMudhra reports key compromise; CERT-In warns of fake websites
- Tracking site data: impacted-intermediates.json (all 16 certificates with serials, dates and hashes)
- Tracking site data: roots.json (issuing roots and root store status)
- Tracking site data: chains.zip (chains served by the test hosts)
- crt.sh entry for EM DV TLS CA G3B
Last reviewed: 22 October 2026. This is a developing story; check the linked advisories for the latest status.