Chrome Refused a Certificate From the Compromised eMudhra CA. Curl on the Same Machine Returned 200.
Apple’s new support page explains why a Mac can block a certificate in Safari and accept it in Terminal. I ran the same test on my Linux machine. It had three trust lists, and only Chrome’s refused the certificate.
Apple published a support article yesterday, 29 October, called “About the compromised eMudhra intermediate CAs.” Most of it is what you’d expect. The private keys of eight intermediate certificate authorities run by eMudhra were compromised, six of them issue TLS certificates, and Apple has been blocking the twelve certificates for those six since 19 October. On 23 October it also began blocking the root they chain to, emSign ECC Root CA - G3.
Further down the page, Apple gets specific. On a Mac, it says, curl, git, python3, ruby, perl and openssl “check certificates against /etc/ssl/cert.pem.” For certificates that chain to a root in that file, “these tools don’t check Apple’s block or whether the certificate has been revoked.” Safari and Mail are covered automatically. The command-line tools on the same machine wait for “a future macOS update.”
So one Mac carries two lists of what to trust, and only one of them got the fix. The machine I work on runs Linux, so this morning I tested whether it had the same split.
The test
There is a public test page at dv-g3b-emudhra.we-have-a-problem.com that serves a certificate issued by one of the compromised intermediates. I didn’t take that on trust. I pulled the chain with openssl and compared fingerprints. The intermediate is EM DV TLS CA - G3B, issued by emSign Root TLS CA - G3, and its SHA-256 fingerprint starts 42C4ACCD. That is the third entry in Apple’s blocked list, character for character. The site’s own certificate is dated 20 October 2026, the day after Apple started blocking.
Then I asked five clients on the same Linux machine to open the page, at 07:24 UTC on 30 October:
- Chrome 154: refused. “Your connection is not private,” error NET::ERR_CERT_AUTHORITY_INVALID.
- curl 8.5.0: HTTP 200.
- openssl 3.0.13 s_client: “Verify return code: 0 (ok).”
- python3 3.12, plain urllib: HTTP 200.
- Node.js 20.20.2: HTTP 200.
The page that curl downloaded says, in full: “Your client successfully connected to the site. That’s bad!”
Why the answers differ
Chrome made its own decision, and the other four never asked Chrome. Curl, openssl and Python’s standard library on Ubuntu all read the operating system’s bundle, /etc/ssl/certs/ca-certificates.crt, which comes from the ca-certificates package. I checked: curl reports that file as its CAfile, and Python’s default cert.pem is a symlink to it. Node.js uses neither by default. Its documentation describes the bundled store as “a snapshot of Mozilla CA store that is fixed at release time.”
That left two lists to look at, and one more thing.
First, the operating system’s list. The tools ran in an Ubuntu 24.04 environment with ca-certificates version 20260601~24.04.1 installed. Running trust list showed emSign ECC Root CA - G3 still marked as a trust anchor. Ubuntu had already shipped a fix. The changelog for version 20260816ubuntu0.24.04.1, dated 20 October, opens with “Blacklist the following CA cert due to intermediate cert compromise” and names emSign ECC Root CA - G3. Launchpad shows it published to noble-updates on 21 October. The fix had been out for nine days, and this environment hadn’t installed it.
Get Josepollman’s stories in your inbox
Join Medium for free to get updates from this writer.
That’s the most ordinary failure there is, and the reason I’m writing it down. Nothing was wrong with Ubuntu’s response. A distribution can only ship the update. Containers, build images and long-lived dev environments only get it when someone rebuilds or upgrades them, and a browser that updates itself in the background gives you no hint that the rest of the machine is behind.
Second, Node’s built-in list. I counted the roots compiled into Node 20.20.2: 144, four of them emSign, including emSign ECC Root CA - G3. Node’s October security release lists “ca-cert (eMudhra Intermediate CA Compromise)” as a fix “on 26.x, 24.x, 22.x.” Version 20 isn’t on that line. Node’s own release schedule puts its end of life at 30 April 2026, and the security post says plainly that “End-of-Life versions are always affected when a security release occurs.” This copy of Node 20 was installed through nvm. Upgrading the operating system’s certificates would not have changed its answer, because by default it never reads them.
Then revocation. Apple’s page says eMudhra and Sectigo have revoked the affected certificates. None of the four tools refused the page because of it. A revoked intermediate with a trusted root above it still verified as fine.
The Mac version of the same check
If you’re on a Mac, Apple gives a one-line check in step 4 of its article:
openssl crl2pkcs7 -nocrl -certfile /etc/ssl/cert.pem | openssl pkcs7 -print_certs -noout | grep -E 'emSign ECC Root CA - G3|AAA Certificate Services'If that prints emSign ECC Root CA - G3, the command-line tools still trust the chain. Apple’s article walks through removing it by hand and adds two warnings that are easy to miss.
The first is that removing the emSign root “doesn’t block the six certificates that Sectigo cross-signed,” because those still verify through AAA Certificate Services. Apple gives a second command for that root too, and warns that removing roots can stop these tools from verifying sites that chain to them through intermediates that weren’t affected.
The second is that “a macOS software update can replace /etc/ssl/cert.pem with Apple’s version.” Until the update with Apple’s own fix arrives, any update can quietly put the root back, so Apple says to re-run the check after each one.
On Ubuntu or Debian, trust list | grep -A3 "emSign ECC Root CA - G3" does the same job. If it prints a trust anchor, upgrade ca-certificates. For Node, node -v is enough. Node 20, and anything older than the October security releases on the 22, 24 and 26 lines, doesn’t have that update.
Where this touches my own work
I run notspoofed.com, a free checker for a domain’s email authentication records. One of the things it looks at is MTA-STS, which tells other mail servers to use TLS when delivering to your domain and to refuse a certificate that doesn’t check out. When I run gmail.com through my checker, it shows “MTA-STS enforce” along with the policy’s mode, MX names and max_age. Those last values aren’t in DNS. They come from a policy file my checker fetches over HTTPS from mta-sts.gmail.com.
The MTA-STS standard, RFC 8461, says both the policy host and the receiving mail server must present a certificate that will “chain to a root CA that is trusted by the Sending MTA.” It says sending servers are “expected” to use “a set of trusted CAs similar to those in widely deployed web browsers and operating systems.” Revocation checking is a MAY.
In other words, the protection is exactly as current as the root list on whichever server does the sending, or the fetching. My browser has no say in it. Every mail server and every HTTPS-fetching backend has its own answer to “do I trust emSign ECC Root CA - G3 today?”, and the only way to know that answer is to ask that machine.
What I’m taking from it
Chrome on this machine refused the bad certificate. Chrome’s list was one of three on it.
The checks take less than a minute each. Open a page that shouldn’t work, from each tool you actually use, and see which ones refuse. The public test page above is enough for this one incident. The habit is the part that carries over: a fix that reached your browser has told you nothing about curl, your language runtime, your containers or your mail server.
Sources: Apple Support, “About the compromised eMudhra intermediate CAs” (published 29 October 2026); Ubuntu ca-certificates changelog, version 20260816ubuntu0.24.04.1; Node.js October 2026 security releases and release schedule; RFC 8461 sections 3.3 and 4.2. All tests run on 30 October 2026.
I build free tools for checking email authentication and vendor details. notspoofed.com is the email one.








