eMudhra, Brotli, and the Long Tail of a Security Fix

Fixes for eMudhra and Brotli are out. Getting them everywhere they’re needed means tracking down bundled libraries, runtimes, and certificate stores.

  • Jonathon Klobucar
    Jonathon Klobucar
6 min read
eMudhra, Brotli, and the Long Tail of a Security Fix

How much software do you have to update to fix one vulnerability, let alone two far-reaching ones in the same week?

Our corner of the internet was getting impatient waiting for Node’s eMudhra fix to drop. The certificate block had merged, and we were ready to update Node, rebuild, and move on.

Then the October 21 release dropped, and we got Brotli too. That covered both problems in Node. But how much else used that same decoder? It was tucked into other applications and runtimes, and now we had more places to look.

And eMudhra had its own version of the same problem. Your browser could reject the compromised certificates while a command-line tool on the same machine still trusted them. Which other programs accepted them? Which certificate stores were they using? Updating Node only covered part of it.

eMudhra: a trust decision that traveled off the map

On October 17, a researcher showed they had recovered eight eMudhra intermediate CA private keys by signing a message with each one. Scott Helme later recovered them from the public certificates on his laptop in less than a second.

The values included 4, 56, and 115. These were supposed to be 384-bit private keys, with roughly 3.94 × 10¹¹⁵ possible values. The actual keys all fit in eight bits. You could try every possibility by counting to 255.

eMudhra says the keys came from a flawed key-generation ceremony in April 2025 and that the intermediates never issued customer certificates. That doesn’t tell us whether someone else used them. The weak keys had gone unnoticed for nearly eighteen months.

Mozilla found no certificates from those intermediates in Certificate Transparency logs at disclosure. That helps, but plenty of clients don’t require that logging. Someone could have used the keys to forge certificates those clients would accept without leaving a record in those logs.

Chrome and Firefox could push out a block without waiting for an ordinary software release. Mozilla says its OneCRL update reached Firefox users with standard configurations in less than three hours. Chrome also pushed a CRLSet block that evening. The disclosure site even had a handy test for checking your browser.

Outside the browser, the answer depended on which program you asked. Many clients needed a new certificate bundle or a change to their verifier. Revoking the certificates at the CA did little for clients that never checked that information.

There were multiple ways to trust these certificates, too. Mozilla identified paths through three roots, including Sectigo’s AAA Certificate Services. Its advice was to block the compromised intermediates where possible. Removing the roots that trusted them was another option, but could break legitimate connections too. Removing just one might still leave another trust path open. Mozilla’s guidance

Go addressed the problem with a verifier change in versions 1.27.3 and 1.26.10. Getting that change into an application meant rebuilding it with the patched toolchain. Installing a new Go compiler would leave an existing executable exactly as it was.

Brotli: the decoder inside the runtime inside the product

The Brotli advisory led to a similar search. CVE-2026-111497 could corrupt memory when an application decoded malicious compressed input. Node shipped a fix, but the vulnerable code came from Google’s Brotli library. Other projects had shipped it too.

Bun was one of them. Its fetch implementation automatically decodes Brotli responses, so a server the application contacts can feed data to the decoder. Bun 1.4.4 updated the library. But if you had built an executable with bun build --compile, that executable carried its own runtime. It still needed rebuilding. Bun advisory

Then there was Python. Requests automatically decodes Brotli responses when brotli or brotlicffi is installed, including when another dependency brings it in. You don’t have to import Brotli in your application to end up using it.

On Sunday, October 25, Microsoft published a .NET advisory for the same Brotli flaw. Applications decoding untrusted Brotli data were affected there too. Four days after the Node release, there were still more places to check.

And the list keeps going. The Brotli library can come along with another dependency or get compiled into a runtime, without “brotli” showing up in your application’s dependency list. Have a look at Broccoli2Shell’s list of bundled copies. Updating Node only gets you so far. You still have to find the other copies and work out which ones need fixing.

Where the fix gets stuck

Shipping a runtime or library with your application is convenient. When it needs a security fix, you own the job of replacing that copy. Updating the system’s copy won’t replace the one bundled with your application. Even applications using a shared library may need a restart to load the corrected version.

With certificates, you can update a package and still leave the trust decision untouched. An SDK may hand verification to a library, runtime, or operating system. Another tool may read its own certificate bundle.

The macOS example makes this easy to see. Protections delivered through Apple’s security frameworks do not automatically extend to command-line tools reading /etc/ssl/cert.pem. A browser check can look good while another program on the same machine still accepts the compromised chain.

This is the part that makes “we updated” an incomplete answer. Which copy changed, and is the application actually using it?

And if we start finding more of these?

There’s an AI connection here too. Node.js credits OpenAI’s Codex Security researchers with reporting the Brotli flaw. eMudhra says AI-assisted tools reportedly helped recover its weak keys.

Great, we’re finding the bugs. Now we have to find everywhere they ended up. If AI helps more of these come out of the woodwork, maintainers and product teams have more updates to chase down.

Those same tools can help with the digging: tracing dependencies, finding bundled copies, and figuring out what needs rebuilding. We still need to check what actually shipped.

And the agents doing some of that work? They’re using the same runtimes, certificate stores, and decoders. Now they’re deciding what to fetch on their own, without someone nitpicking every URL or checking everything that comes back.

Getting the fix the rest of the way

Chrome and Firefox already had the infrastructure to get those certificate blocks out. Most applications don’t have a browser vendor’s update system or that level of established trust. Building either isn’t a weekend fix.

But we can make the cleanup less of a scavenger hunt in a haunted house:

  • Know what each release contains. Track application dependencies alongside bundled runtimes, libraries, toolchains, and certificate settings.
  • Have a rebuild path ready. Automate the builds and checks you’ll need when a dependency changes. If you’re waiting on another project, give someone responsibility for following its release.
  • Don’t just wait for a patch. Disable the affected feature where you can, or block untrusted input from reaching it. Microsoft gives Brotli examples for .NET. Check that the workaround works, and keep someone on it until the fix ships and gets deployed.
  • Check the application itself. Test certificate rejection through the verifier it actually uses. Confirm that a corrected decoder made it into the shipped artifact and the running service.
  • Track installation as well as publication. A release being available does not mean people are running it. Be clear about what needs to be replaced or restarted.

So, how much software do you have to update? Turns out, more than the first advisory might suggest. eMudhra and Brotli sent teams looking for s̶p̶o̶o̶k̶y̶,̶ s̶c̶a̶r̶y̶ s̶k̶e̶l̶e̶t̶o̶n̶s̶ affected components buried in their dependencies. As more flaws come to light, finding those copies and getting them patched quickly needs to become routine.

Stay ahead of threats

Subscribe to our newsletter

Get notified when we publish new security blog posts!