Back to Blog

macOS 27.2 Undid the eMudhra Fix. Your Mac's git Trusts It Again.

Apple blocked the compromised eMudhra CAs in Safari within two days, but curl, git and python3 on macOS still trust /etc/ssl/cert.pem, and macOS 27.2 reverted the manual fix. How to check your Mac, Homebrew and macOS CI runners.

CertGuard TeamSSL Security Experts11 min read
A half-open laptop on a dark wooden surface in an otherwise dark room, its screen casting orange, red and blue light across the keyboard and trackpad

Safari got the fix in two days. Your git didn't.

On Monday Apple shipped macOS Golden Gate 27.2. If you'd read Apple's own support article the week before and carefully cut two root certificates out of /etc/ssl/cert.pem, the update put things back the way they were. Your Mac's git trusts the compromised eMudhra chain again.

Dennis Jackson, who runs the eMudhra checker site for the incident, wrote on 28 October that 27.2 "did not fix the issue and undid the workaround that users had applied by hand." The post hit 1,113 points on Hacker News within a day, and the thread is mostly people discovering that their Mac has more than one opinion about which CAs to trust.

Recap, in case you were offline: eight eMudhra intermediate CAs had private keys that were small integers, one of them literally the number 4. Browsers blocked them within hours of the report on 17 October. We already went through the server and container side and the revocation fallout. Which leaves the machine you're reading this on.

Two trust stores, and one of them is a text file

Apple's support article 149555, published 23 October, says Apple started blocking the compromised intermediates on 19 October. Safari, Mail and anything built on Apple's networking and security frameworks refuse them. Then comes the paragraph that matters:

some command-line tools included with macOS or the Xcode Command Line Tools (including curl, git, python3, ruby, perl, and openssl) check certificates against /etc/ssl/cert.pem. For certificates that chain to a root CA certificate in this file, these tools don't check Apple's block or whether the certificate has been revoked.

So your Mac has two trust stores. The keychain is a database with trust settings, and Apple can hang a blocklist off it. /etc/ssl/cert.pem is a flat PEM file. A flat file knows one word about a root: trusted. It has no way to say "trust this root, except for these eight intermediates under it." The block Apple pushed to Safari has nowhere to go in that format. The only fix that fits in a PEM file is deleting the root.

Apple's article promises the file "will be updated in a future macOS update." 27.2 wasn't it.

macOS 27.2 put the root back

Apple's security releases page lists macOS Golden Gate 27.2, Tahoe 26.7.2 and Sequoia 15.8.2 all on 26 October. Nine days after the report, and none of them shipped a new cert.pem.

And then there's this line, from Apple's own article: "A macOS software update can replace /etc/ssl/cert.pem with Apple's version." Apple documents a workaround and warns, in the same breath, that its next update may wipe it. Apply it on the 24th, install 27.2 on the 27th, and you're back where you started. Nothing tells you.

Remember that one after eMudhra is forgotten. Hand-edit a file the OS vendor owns and you've bought yourself time until the next update. Nothing more. If you rely on the edit, something has to re-check it after every update, and a wiki page won't.

Homebrew wasn't the escape hatch either

Half the HN thread replied with some version of "I use Homebrew's git and curl, so I'm fine." Partly true. As of this week.

On macOS, Homebrew's ca-certificates formula mixes two sources. Its post-install script builds $(brew --prefix)/etc/ca-certificates/cert.pem by exporting the trusted roots from the System keychains first, then appending Mozilla's certificates. Apple's block targets the intermediates. The emSign root itself is still in the keychain. On 20 October Homebrew added an exclusion list that drops certificates by SPKI hash, in revision 2026-09-25_1. The list survived the move to Mozilla's 20 October extract, even though that extract has no emSign G3 root left in it. Makes sense: the keychain half would bring it straight back.

Then there's git. Until 28 October, Homebrew's git formula linked against macOS's system libcurl, which reads /etc/ssl/cert.pem. One HN commenter running Homebrew git 2.56.0 reported it stayed vulnerable until they patched the system file. The fix is a commit titled "git: do not depend on macOS's system cURL", shipped as 2.56.0_2, and this comment in the formula: TODO: Replace with uses_from_macos once Apple fixes their CA bundle.

Homebrew's curl reads Homebrew's bundle through openssl@4, so it was fine from the 20th, if you upgraded. Homebrew's git, from the 28th. Neither helps a script that calls /usr/bin/git by absolute path.

Your CI runners are Macs too

Laptops at least get updated by someone who notices. GitHub's hosted macOS runners are Macs with a frozen image and a preinstalled Homebrew. They also hold your deploy credentials.

The curl project found out on 28 October. Viktor Szakats's CI log shows /usr/bin/curl (8.7.1, LibreSSL 3.3.6) on a runner connecting happily to the test host, against a /etc/ssl/cert.pem dated 1 August. The preinstalled Homebrew bundle at /opt/homebrew/etc/ca-certificates/cert.pem was dated 7 September. That's older than the Homebrew fix, so it contained the compromised roots too. Both connected. His PR strips the certificates as the first step of every macOS job, and says the Homebrew part can go "as soon as new runner images ship with ca-certificates package's latest version."

Now think about what your macOS jobs do all day. They clone and pull dependencies over HTTPS, often with a notarization key or an App Store Connect token sitting in the environment. I wouldn't wait for GitHub to refresh the image.

Find out what your machine actually trusts

Start with the probes. The checker hosts serve leaf certificates signed with the compromised keys. The noct variants were never logged to Certificate Transparency, so they test exactly the clients an attacker could hit without anyone seeing it. You want a certificate error from every one of these:

/usr/bin/git ls-remote https://git-emudhra.we-have-a-problem.com/check.git
/usr/bin/curl -sS -o /dev/null https://dv-g3b-noct-emudhra.we-have-a-problem.com/
/usr/bin/curl -sS -o /dev/null https://dv-g3b-aaa-noct-emudhra.we-have-a-problem.com/

Run them again without the /usr/bin/ prefix, because whatever's first on your PATH is what your scripts call. which -a git curl python3 shows you every copy.

Then look for bundles. A Mac that's been a dev machine for a few years collects PEM files. Homebrew keeps one. Every Python virtualenv with certifi in it has another, and plenty of SDKs bring their own. This walks the usual places and flags any bundle that still has either root:

#!/usr/bin/env bash
pat='emSign ECC Root CA - G3|AAA Certificate Services'
find /etc/ssl /opt/homebrew /usr/local "$HOME" \
  -type f \( -name 'cert.pem' -o -name 'cacert.pem' -o -name 'ca-bundle.crt' \) 2>/dev/null |
while IFS= read -r f; do
  n=$(openssl crl2pkcs7 -nocrl -certfile "$f" 2>/dev/null \
      | openssl pkcs7 -print_certs -noout 2>/dev/null | grep -cE "^subject=.*($pat)")
  [ "${n:-0}" -gt 0 ] && echo "STILL TRUSTS ($n): $f"
done

With a lot of node_modules under $HOME this takes a while. Let it run. I tested the logic against curl's Mozilla extracts: the 25 September bundle gets flagged for the emSign root, the 20 October one comes back clean.

Node ignores all of these files. It ships a Mozilla snapshot "fixed at release time", in the words of its own docs, so the fix is a Node upgrade. The checker lists 22.23.4, 24.22.1 and 26.12.1. On a fixed build this prints 0. I checked it on 24.22.1:

node -e 'const {X509Certificate}=require("crypto");console.log(require("tls").rootCertificates.filter(p=>/emSign ECC Root CA - G3|AAA Certificate Services/.test(new X509Certificate(p).subject)).length)'

For Python, pip-installed requests uses certifi, and you want certifi 2026.10.19 or later. Skip 2026.10.18, which also pulled roots that are still trusted.

Strip the roots, then prove it in CI

On a laptop, Apple's article gives the commands. Back up the file, remove emSign ECC Root CA - G3, optionally remove AAA Certificate Services. Do the optional one as well. Mozilla's bundle dropped AAA a while ago, and curl's extract from 25 September already lacks it, so removing it puts your Mac where Firefox already is.

Stop there, though. emSign Root CA - G1 is eMudhra's RSA root. Mozilla isn't distrusting it, and eMudhra is moving customers onto it. The curl project's CI step also strips G1 from the Homebrew bundle. On a throwaway runner, who cares. Paste it into a laptop and you'll break sites that did nothing wrong.

In CI the strip matters less than the assertion after it. If a future runner image changes the file layout, the awk quietly matches nothing, and you want the build to go red when that happens:

      - name: Remove compromised eMudhra roots
        if: runner.os == 'macOS'
        run: |
          t="$(mktemp)"
          awk -v s='=== /C=IN/OU=emSign PKI/O=eMudhra Technologies Limited/CN=emSign ECC Root CA - G3' \
            '/^(===|###) /{skip=0} $0==s{skip=1} !skip' /etc/ssl/cert.pem |
          awk -v s='=== /C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services' \
            '/^(===|###) /{skip=0} $0==s{skip=1} !skip' > "$t"
          [ -s "$t" ] && sudo install -m 0644 -o root -g wheel "$t" /etc/ssl/cert.pem
          rm -f "$t"
          for f in /etc/ssl/cert.pem "$(brew --prefix)/etc/ca-certificates/cert.pem"; do
            if openssl crl2pkcs7 -nocrl -certfile "$f" | openssl pkcs7 -print_certs -noout \
                 | grep -qE 'emSign ECC Root CA - G3|AAA Certificate Services'; then
              echo "::error::$f still trusts a compromised eMudhra root"; exit 1
            fi
          done

The two awk filters are Apple's, chained. If the Homebrew check fails, brew update && brew upgrade ca-certificates rebuilds the bundle with the exclusion list. That's slow on a runner. curl's composite action strips the PEM blocks directly instead. Pick either. Just keep the check.

Your laptop is part of the supply chain

My opinion, for what it's worth: teams sweat over the trust stores on their servers and ignore the one on the laptop that pushes to production. The laptop is the thing on hotel Wi-Fi. It has your SSH keys and your cloud sessions on it.

Look at how this one went. Apple documented a manual fix, then shipped an update that undid it. Homebrew, the thing everybody uses to get away from Apple's tooling, had its git reading Apple's file the whole time. And the CI fleet ran on an image older than both fixes.

Monitor what your developer machines and macOS runners trust, the same way you do for servers. Put the probes above in a script your MDM or a login hook runs after every OS update. Track runner image versions like you track base images. If you already keep a certificate inventory, add a column for which bundle each client reads. And if your Git remotes still use HTTPS with a token, this is a good week to rethink what your tooling trusts. An SSH remote with a pinned host key doesn't care what's in /etc/ssl/cert.pem.

Frequently asked questions

Is Safari on macOS affected by the compromised eMudhra certificates? No. Apple says it started blocking the compromised intermediates on 19 October 2026 in Safari, Mail and apps that use its networking and security frameworks. The exposure is limited to tools that verify against /etc/ssl/cert.pem, such as the bundled curl, git, python3, ruby, perl and openssl.

Did macOS Golden Gate 27.2 fix /etc/ssl/cert.pem? No. 27.2 shipped on 26 October 2026 without an updated file, and according to the eMudhra checker site it undid manual edits users had made by following Apple's instructions. Apple's own article warns that a macOS update can replace the file, so re-run the check after every update until Apple ships the corrected bundle.

Is Homebrew's git safe now? Homebrew's git 2.56.0_2, released on 28 October 2026, links against Homebrew's own curl instead of macOS's system libcurl, so it no longer reads /etc/ssl/cert.pem. It still depends on Homebrew's ca-certificates bundle, which needs revision 2026-09-25_1 or later to exclude the compromised roots, so upgrade both and run the git probe to confirm.

Should I also remove emSign Root CA - G1 from my Mac? No. G1 is eMudhra's RSA root, Mozilla has said it is not distrusting it, and eMudhra is moving affected customers onto it. Removing it would break legitimate sites without protecting you from the compromised keys, which sit under the emSign ECC Root CA - G3 hierarchy and the Sectigo AAA Certificate Services cross-sign.

Do Go binaries on macOS need the same fix? Generally not. Go on macOS verifies through the platform's own verifier, which has Apple's block, and Go 1.27.3 and 1.26.10 also hardcode the eight compromised keys. Binaries built with older Go toolchains still rely on whatever the platform verifier says, so keep macOS itself updated.

Related posts

Never miss an expiring certificate again

CertGuard watches your SSL certificates and domains, and alerts you long before anything expires. Free for your first five domains.