The Brotli Flaw Inside .NET, PHP, Envoy, and Node.js
A compression bug that shipped in 2018 became a remote code execution flaw last week. CISA listed it 5 days after the CVE appeared. The hard part is not patching it. The hard part is finding it.
What Happened?
Google published CVE-2026-111497 on Thursday, 22 October: an out-of-bounds write in the Brotli decoder. Researchers call it Node2Shell. A single compressed request body, with no login, can corrupt memory on a server that unpacks attacker-supplied Brotli data. Google rates it 9.2 and critical. Threat intelligence firm ELLIO recorded exploit traffic hitting its sensors at 15:08 UTC on Monday 26 October, aimed at Node.js 24.22.0. CISA added the flaw to its Known Exploited Vulnerabilities catalog the next day, with a federal deadline of Tuesday 10 November.
What Is the Impact?
Brotli sits inside far more than Node.js. Affected software includes .NET, Bun, Envoy, Istio, FFmpeg, Apache Arrow, ClickHouse, and Python HTTP clients. The bug entered Brotli 1.0.3 in March 2018, so it has shipped quietly for more than 8 years.
One decoder. Eight ecosystems shipping it.
The flaw entered Brotli 1.0.3 in March 2018 and travelled wherever the library went. Each product needs its own fixed release, because patching Brotli upstream does not patch the copy inside a shipped binary.
24.22.1
26.12.1
9.0.22
10.0.14
8.4.27-1
8.3.36-1 · 8.2.35-1
1.38.6, 1.37.8
1.36.12
brotlicffi 1.2.1.0
brotli 0.9.2
Alpine 3.21 to edge
Sources: Google CVE record for CVE-2026-111497, ELLIO advisory tracking, Microsoft .NET out of band update 25 Oct 2026, PHP.net 26 Oct 2026, vendor advisories compiled 28 Oct 2026.
Your Version Number Is Lying to You
This is the part that will cost teams their weekend. Node.js reports its bundled Brotli as 1.2.0 whether or not the build is patched, so the obvious check tells you nothing. PHP shipped fixed Windows builds on Monday, 26 October as 8.5.12-1, 8.4.27-1, 8.3.36-1, and 8.2.35-1, where only the suffix changed, and the PHP version stayed the same. Container scanners that read package manifests often miss the Brotli copy compiled into the official Node.js binary. Go by the release version of the product, not by what the library reports.
Was Anyone Actually Popped?
Careful here. ELLIO got a shell against its own vulnerable targets, usually around the fifth attempt. The attacker traffic it captured scored zero hits in 50 tries, suggesting a first-generation attempt fired before the final stage finished. So this is proven exploitable and actively targeted, but nobody has published a confirmed compromise yet. Treat it as exploited and patch anyway.
How to Avoid This
- Move to Node.js 22.23.4, 24.22.1 or 26.12.1
- Patch .NET to 8.0.33, 9.0.22 or 10.0.14
- Rebuild images; do not trust the manifest
- Turn off automatic response decompression where unused
- Hunt for Brotli-encoded request bodies at the edge
The Fix Took One Day. Finding Every Copy Took Longer.
Brotli is compiled into runtimes, proxies, media tools, and language packages, and most of those copies never show up in a dependency list. The work is knowing where it runs before the deadline, not after.
- Finds the flaw on the asset carrying it, including runtimes where the library is compiled in rather than listed
- Shows KEV status, exploit prediction score, and exploit evidence on the same asset, so a quiet score does not bury an active threat
- Ranks an internet-facing service that accepts compressed request bodies ahead of an internal one that never will
- Routes runtime alerts, such as a web worker spawning a shell, into the SOC Teammate for investigation
- Holds every consequential change behind a named approver in Slack or Teams
Closing
The catalog moved fast on this one. Five days from CVE to listing, against 105 days for the Magento flaw listed the same morning. Speed was never the problem here. Knowing what you are running.