Server security
The emSign Key That Was the Number 4: Why Browsers Pulled It and What It Means for Your Code
By Avery Parker, Diversified Tech Solutions ·
Most security stories are complicated. This one has a detail that is easy to understand: one of the secret keys meant to protect a piece of the internet's trust system was the number 4. Here is what that means, why browsers acted so quickly, and why the browser is only the tip of the iceberg for people who run servers, software or code.
1. The story
When you see the padlock next to a web address, your browser is checking a digital certificate. A certificate is like an ID card for a website. It says "this really is your bank," and it is vouched for by a company called a certificate authority.
Certificate authorities vouch for websites by digitally signing their certificates. To sign, they use a private key: a very large secret number that only they are supposed to know. Your browser, phone and many apps carry a built-in list of authorities they trust, starting with top-level "root" certificates and the "intermediate" certificates that sit below them and do the daily signing. If a trusted intermediate signs something, software that relies on that list generally accepts it.
The whole system depends on those private keys being practically impossible to guess. For a key of the type involved here, the number is supposed to be extremely large.
Eight eMudhra (emSign) intermediate certificates had private keys with values under 256. One was literally 4. According to the Mozilla bug report, a key that small can be recovered with modest effort, by generating the first 256 possible keys and comparing. Security researcher Scott Helme recovered all eight in under a second on a laptop, as reported by CyberScoop.
Six of the eight were for website (TLS) certificates and two were for code signing. All of them sat under the "emSign ECC Root CA - G3" root, and each was also cross-signed by Sectigo's "AAA Certificate Services," according to The Hacker News.
Why that matters: once a signing key is known, it is no longer a secret. Someone holding the key could create a certificate that looks properly signed by a trusted authority, for a website name of their choosing. A fake bank site or a fake copy of a software download site could present a certificate that software relying on that trust list would accept. In that situation, the certificate alone no longer proves who you are talking to.
In its incident statement, eMudhra says the weak keys came from a key wrap and unwrap step in its April 30, 2025 key ceremony. It says only one of the eight was in production and none issued a certificate to an end website. eMudhra is exiting the global TLS certificate business.
There has been no confirmed malicious use, according to eMudhra and CERT-In. At the same time, it cannot be proven that there was none between April 2025 and now, and public tooling that can use these keys now exists. That combination is why the response was fast.
2. Why browsers pulled it
The browser makers moved within days. All times are Eastern.
- October 17: The issue was reported around 2:05 PM. By about 3:45 PM, Google had blocked the keys in Chrome. By about 6:59 PM, Mozilla had pushed protection to Firefox.
- October 19: Apple blocked them.
- October 20: Microsoft blocked them, and Mozilla removed the emSign root from its trust store.
A public tracker follows each vendor's response.
The next step is October 27. That morning (Pacific time), Chrome's root store removes the emSign root. After that, websites still using an emSign ECC G3 certificate are expected to stop working in Chrome. If you own a website, now is the time to check who issued your certificate and replace it if it is eMudhra or emSign.
3. Chrome is the tip of the iceberg: the stack
Browsers are the visible part of this. Most update automatically and they have extra safeguards. The larger remaining risk is everything else that makes secure connections on its own.
A lot of software carries its own list of trusted certificate authorities instead of using the browser's. That includes Python tools (pip, certifi, uv), Node.js and npm, Go programs, Rust applications, Docker images, and older devices and apps. These tools generally do not enforce Certificate Transparency, the public logging system browsers use to catch certificates that were never properly issued. So if one of them has not been updated, a forged certificate made with one of these keys could be accepted by it.
Think about what that software does. Package managers download code from repositories. Build tools pull container images. Applications fetch updates. If an attacker can make a fake repository look genuine to an unpatched tool, the tool could in principle be handed a tampered package instead of the real one, without an obvious sign that anything was wrong. To pull that off, an attacker would need to be on the network path between you and the real server, for example on public Wi-Fi, through a compromised router, at the ISP or state level, or by hijacking DNS or internet routing. That is a meaningful hurdle, but not one to count on.
To be clear, nothing in Python, pip or PyPI was breached. The repositories are fine. The issue is that older copies of the tools that talk to them still trust keys that are now public.
The two code-signing intermediates are worth noting too. Code signing is how software publishers vouch that a program really came from them, so those keys sit in the same trust conversation.
Fixed versions so far:
- Python: pip 26.2.2, certifi 2026.10.19, uv 0.13.4, sigstore 4.5.1, conda 26.9.4, pixi 0.82.1. CPython 3.15.1, 3.14.9 and 3.13.17 ship the fixed pip. Python 3.11 and 3.12 will not get a pip bump. See the Python Software Foundation notice.
- Node.js: 26.12.1, 24.22.1 and 22.23.4, per the Node.js security release.
- Go: 1.27.3 and 1.26.10, and you need to rebuild your binaries, per the Go announcement.
- Rust: webpki-roots 1.0.10, rustls-webpki 0.103.16, rustup 1.29.2.
- Linux: Debian has fixed ca-certificates in DSA-6572-1 for Debian 13 (trixie) and DLA-4845-1 for Debian 12 (bookworm), and Ubuntu has USN-8944-1 and USN-8944-2. As of October 21, Red Hat offered a workaround only.
- Docker: As of October 21, the official Python images still shipped pip 26.2.1.
4. What to do
If you own a website
Check the issuer of the certificates on the domains and subdomains you run.
- In a browser: click the padlock (or site information icon) next to the address and open the certificate details. Look at "Issued by" or "Issuer."
- From a command line:
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -issuer
If the issuer is eMudhra or emSign, ask your web host or certificate provider for a replacement from a different authority, install it, and run the check again. Do it before October 27.
If you run the stack
Start with the system certificate store, then the tools.
- Update ca-certificates on your servers with your package manager, for example
sudo apt update && sudo apt install --only-upgrade ca-certificates. - Upgrade pip safely in each virtual environment. Do not run a plain
pip install --upgrade pipthrough an old pip, because that download is the exposed path. Use the hash-pinned command from the PSF notice, which only installs a file matching a known checksum:python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70"Once pip 26.2.2 is in place, use it to upgrade certifi to 2026.10.19 or later. Alternatively, upgrade from a trusted network after your system certificate store has been updated.
- Update uv using your updated system certificates:
UV_SYSTEM_CERTS=true uv self update - Update Node.js to a fixed release (check with
node --version). - Update Go and rebuild your Go tools and services (check with
go version). - Update Rust dependencies to the fixed crate versions and rebuild.
- Rebuild Docker images without cache so they pick up fresh layers, and install the pinned pip in the Dockerfile:
docker build --pull --no-cache -t your-image .RUN python -m pip install "pip @ https://files.pythonhosted.org/packages/3f/06/3e4420302363fbb71be3c7f35ce042f54bfca330e3e66b3a2e3c4cca579f/pip-26.2.2-py3-none-any.whl#sha256=fd7f4dfa8190e014013b9f08f3e973f4e4c26ffd179a204895533a7254813a70" - List older devices and apps that no longer get updates, and plan to update, replace or isolate them.
Everyone else
Update Chrome, Edge, Firefox and Safari, then fully close and reopen them so the protections apply. Install operating system updates on Windows, macOS, iOS and Android. Up-to-date browsers have been protected since October 17 to 20.
We can help
If you would like a second set of eyes, Diversified Tech Solutions can check which certificates your sites are using and whether your servers and tools have the updated trust lists. Call 423-888-0252, email avery@diversifiedtechsolutions.com, or visit diversifiedtechsolutions.com.
