
One certificate authority, eMudhra, used private keys so weak they could be guessed in a second. One key was literally the number 4. Keys like these could be used to forge a “secure” website for a bank, payment service, or virtually anyone else.
Browsers have already protected their users. Servers, however, have not necessarily done so. If your server runs scripts, websites, or applications that connect to other services, update its list of trusted certificates. It takes about five minutes.
What Is a Certificate?
When you open a bank's website, you see a padlock icon next to the address. It indicates that the connection is secure and the site's identity has been verified. But how does the browser know?
Imagine a notary. You bring in a document, the notary checks it and stamps it. Everyone trusts that stamp. If a document bears the stamp of a well-known notary, people treat it as genuine.
On the internet, certificate authorities (CAs) play the role of notaries. There are around 140 of them worldwide. They issue certificates to websites — effectively, “certified documents.” Browsers, phones, and servers maintain lists of the authorities they trust.
Every notary has a stamp: a private key. As long as that stamp is kept securely hidden, no one can forge the document.
What Happened
eMudhra is an Indian certificate authority trusted by Chrome, Firefox, Apple, and Microsoft.
In April 2025, eMudhra created eight new “stamps” for issuing certificates: six for websites and two for signing software. A bug in a script resulted in tiny private keys.
A normal key is a number more than a hundred digits long. Guessing it would be impossible even over millions of years. All eight eMudhra keys were smaller than 256. One was 4, another was 56, and a third was 115.
It's like a safe with the combination “0004.” An attacker needs no special tools — just a few guesses. Security researcher Scott Helme recovered all eight keys in less than a second.
The mistake was not discovered until October 17, 2026. That means certificates could potentially have been forged for a year and a half. On October 18, eMudhra revoked all eight “stamps.” It is not known whether anyone exploited them.
Why It Matters
With a stolen stamp, an attacker can impersonate anyone — a bank, a payment processor, or an email service, for example.
Here's a simple example. Your online store sends order details to a payment service. An attacker positions themselves between the two and presents a forged certificate. Your server sees the stamp of a “notary” it trusts and hands over the data without complaint. It's like giving an envelope full of money to someone dressed as a courier without checking whether they really work for the delivery company.
This isn't just theoretical. Scott Helme forged a certificate for the payment service Stripe. Popular tools such as curl, Python, and Node.js accepted the forgery without a single warning.
Who Is Affected?
Browsers are already protected. Chrome, Firefox, and Safari have been updated automatically. If you only browse websites, you don't need to do anything.
Servers don't necessarily update themselves. A server has its own list of trusted “notaries.” That list is updated when the operating system is updated. Some applications keep separate lists, which need to be updated independently.
You should update your server if it:
- runs a website or store that connects to payment systems, APIs, or email services;
- runs scripts written in Python, Node.js, Go, or Java;
- uses curl or wget in cron jobs;
- runs Docker containers.
In short, this applies to almost every server.
Update Your System Certificates
The list of trusted “notaries” is stored in the ca-certificates package. You can update it with a simple command.
Ubuntu and Debian:
sudo apt update
sudo apt install --only-upgrade ca-certificatesOn Debian 13, the fixed package version is 20250419+deb13u1 or later.
AlmaLinux, Rocky Linux, CentOS Stream:
sudo dnf upgrade ca-certificates
Alpine Linux:
apk upgrade ca-certificatesOn Alpine, the fixed version is 20261020-r0 or later.
You do not need to reboot the server. However, it's a good idea to restart long-running services: they may have cached the old list at startup.
Update Python, Node.js, Go, and Java
Some applications don't use the system's certificate list. They carry their own. Think of an employee carrying an old address book. You update the company directory, but that employee keeps calling outdated numbers.
PHP, curl, and wget generally use the system list, so step one should be enough for them. The following need to be checked separately.
| Component | How to Check the Version | Safe Version |
|---|---|---|
| Python (certifi package) |
| 2026.10.19 or later |
Node.js |
| 22.23.4, 24.22.1, or 26.12.1 and later |
Go |
| 1.27.3 or 1.26.10 and later |
Java |
| Latest update for your Java release |
Python. Upgrade the package with:
pip install --upgrade certifi
Node.js. This is the same update that fixes a dangerous Brotli vulnerability. So Node.js is worth updating in any case.
Go. Update Go and rebuild your applications. An old compiled application will continue to trust the old “stamps.”
Node.js 20 and earlier will not receive a fix. These releases are no longer supported and need to be migrated to a newer version.
Rebuild Your Docker Images
Each Docker container is a small, separate system with its own certificate list. Updating the host server does not change it. A container is like a suitcase packed a month ago: it still contains whatever you put in it back then.
Here's what to do:
Update the base image — for example, get a fresh release of
node:24,python:3.13, ordebian:13.Rebuild your images:
docker compose build --pull- Restart the containers:
docker compose up -d
The
--pullflag is important. Without it, Docker may use an old base image from its cache, leaving everything unchanged.
What If Something Breaks After the Update?
Along with the bad “stamps,” the trusted list also dropped eMudhra itself — the “notary office” that issued them. As a result, around 30,000 otherwise ordinary certificates also stopped being trusted. Their owners will have to obtain new certificates from another authority.
This means your script or website may stop connecting to a service after the update. You might see errors such as:
certificate verify failed
unable to get local issuer certificate
The service's certificate was most likely issued by eMudhra. Your server no longer trusts it — and that is the correct behavior.
What to do:
- Identify the address your application can no longer connect to.
- Notify the service owner. They need to replace their certificate.
- Wait for the replacement or temporarily use another service.
What not to do: Never disable certificate verification using options such as
verify=Falsein Python or-kin curl. That's like removing your door lock because the key no longer fits. The immediate problem disappears, but the door is left open to everyone.
Checklist
- Updated the
ca-certificatespackage - Restarted long-running services
- Updated Python's
certifipackage - Updated Node.js to
22.23.4,24.22.1, or26.12.1 - Updated Go and rebuilt applications
- Updated Java
- Rebuilt Docker images with
--pull - Checked logs for certificate errors
- Kept certificate verification enabled everywhere
Don't Want to Handle It Yourself?
New vulnerabilities appear every week. With Premium, you don't have to handle them on your own.
Updating one package is easy. The harder part is finding every application on your server that keeps its own certificate list: Python in one place, Node.js in another, and three Docker containers elsewhere. And if payments stop working on your website after an update, every minute costs money.
Zomro offers two options for cases like these.
SOD: We'll Take Care of Everything
Our system administrator will:
- update system certificates;
- find and update Python, Node.js, Go, and Java installations that maintain their own certificate lists;
- rebuild Docker images;
- check that your website and integrations work.
Price: €12.50 for every 15 minutes of work.
Premium: Fast Help When You Need It
A response to a regular technical support request may take up to 10 hours. With Premium, we respond within 5 to 30 minutes. If a payment system or integration breaks after an update, you won't be waiting half a day.

