psf-emudhra-macos-mitigate(8)

Script: /opt/psf-security-patches/pki/emudhra-macos-mitigate.sh. Tool page: eMudhra CA compromise. Source. With the package installed: man psf-emudhra-macos-mitigate.

eMudhra intermediate CA compromise, macOS mitigation  (v1)
Disclosed 20 Oct 2026: https://emudhra.we-have-a-problem.com/

If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation

The private keys of eight eMudhra intermediate CAs can be recovered from their
certificates. macOS blocks them in apps that use Apple's own networking and
security frameworks, but the command line tools that ship with macOS and with
the Xcode Command Line Tools (curl, git, python3, ruby, perl, openssl and pip)
verify certificates against /etc/ssl/cert.pem without checking revocation, and that file still contains the roots the intermediates
chain to. Apple has said it will update the file in a future release. Until
then this script removes those roots from it, the way Apple's support page
(support.apple.com/en-us/149555) and the disclosure page describe, and proves
they are gone.

Homebrew has already shipped a fixed ca-certificates. The script reports its
bundle and the formula version, but never runs brew: brew refuses to run as
root, so update it as your own user (brew update && brew upgrade ca-certificates).

Usage:
  ./emudhra-macos-mitigate.sh [command] [options]

  check (default)  [--online] [--cert-file FILE]
                   read-only; changes nothing, root not needed. Reports
                   whether emSign ECC Root CA - G3 and AAA Certificate
                   Services are still in the system bundle and in
                   Homebrew's, and whether the pip fix is in place.
                   --online also connects to the disclosure site's test
                   hosts with curl: a connection that succeeds means the
                   client still trusts a compromised intermediate.
                   Exit 0 = both roots absent, 1 = emSign ECC Root CA - G3
                   present or a test host accepted, 2 = only AAA
                   Certificate Services remains (your decision, see below)
                   or the bundle could not be read.
  apply            [--include-aaa] [--pip] [--dry-run] [--cert-file FILE]
                   back up the bundle, remove emSign ECC Root CA - G3 from
                   it, and check the result. --include-aaa also removes
                   AAA Certificate Services, which blocks the six Sectigo
                   cross-signed intermediates but may break unaffected
                   sites that chain to it. --pip makes the built-in pip
                   use the fixed system file. Needs root.
  rollback         [--dry-run] [--force]
                   put the original bundle back and remove the pip line.
                   This re-exposes you. It refuses when the bundle has
                   changed since apply (a macOS update) unless --force.
  version          print the script version and exit

Environment:
  CERT_FILE=/etc/ssl/cert.pem        the bundle to check and change
  STATE_DIR=/var/lib/psf-security-patches/emudhra-macos   backups and record
  PLATFORM=Darwin                    override the detected platform
  BREW_PREFIX=/opt/homebrew          where Homebrew is installed
  CURL_BIN=/usr/bin/curl             the curl that --online uses
  PYTHON_BIN=/usr/bin/python3        the Python whose standard library folder holds the
                                     sitecustomize.py that --pip checks
  SITECUSTOMIZE=FILE                 that sitecustomize.py, instead of asking PYTHON_BIN
  LIVE_HOSTS="host ..."              replace the disclosure site's test hosts
  PSF_NO_ROOT_NOTE=1                 hide the note about a root login

Exit codes: 0 done or clear, 1 exposed or a failed change, 2 usage error or
a bundle that could not be read. Every command prints the script version on
its first line.

     PSF_LOCK_WAIT    seconds a run that changes the host waits for another one that is already
                      changing it (default 30), then stops with exit 2; the lock is STATE_DIR/.lock

The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.

The PrivacySafe Ecosystem

Shop at Ivy Cyber

Ivy Cyber offers PrivacySafe products and services in the USA and has partnerships with 3NSoft in Canada and Kuip Limited in the European Union. Enterprise services and consulting are available at ivycyber.com

PrivacySafe Foundation is a 501(c)(3) nonprofit public charity that supports the development of the PrivacySafe applications, along with the components they rely upon: 3NWeb protocols, filesystem, documentation, and reference implementations.

PrivacySafe Foundation

Donations to PrivacySafe Foundation support education, research, documentation, and public code. Purchases from Ivy Cyber support PrivacySafe products, services, hosting, and technical support. Together, we're building a better web.