Broccoli2Shell proves your riskiest code is code you never chose
A Brotli decoder flaw reaches Node.js, Python and more through ordinary web traffic. The lesson is not faster patching: it is knowing where shared code hides.
Photo: Esquilo / Wikimedia Commons (CC BY-SA 3.0)
Which library decompresses the data your server receives? If you can't answer in under a minute, Broccoli2Shell is your problem too, whether or not you've ever typed the word "Brotli" in your code.
The bug is CVE-2026-111497, an out-of-bounds write in Google's Brotli decoder. According to Strobes, it affects Brotli versions 1.0.3 through 1.2.0 and is scored 9.2 (Critical) on CVSS 4.0. Because HTTP clients and servers decode Content-Encoding: br automatically, it reaches Node.js, Python, Bun and other stacks through ordinary web traffic. Node.js shipped fixes on October 21 in versions 22.23.4, 24.22.1 and 26.12.1, as Qualys and others report. The name has shifted several times (Node2Shell, HTTP2Shell, Broccoli2Shell), all for the same single CVE.
The renaming is the real story
Strobes makes a sharp point: the nickname changed three times in four days, and each name reflected who the industry thought was exposed. It began as a runtime patch and turned into a dependency and supply chain problem. We think that arc is the lesson. The vulnerable code sits in a C library that many projects bundle, link or inherit. Nobody "installed" it as a decision. It came with the runtime, the HTTP client or the image.
That is why this is invisible infrastructure. Semgrep notes that the bug isn't in an npm package called brotli, nor in body-parser itself. Yet body-parser hands attacker-controlled compressed data to the decoder. Your dependency scanner can stay quiet while the problem sits one layer below it. Strobes also points to a public tracker, run by independent researchers, that lists projects whose bundled copies were still unpatched on October 24, including the.NET runtime, the PHP brotli extension and the Ruby brotli gem. Updating your distro does nothing for software that vendors its own private copy.
Exposure is about paths, and the worst path is outbound
Not every Node service is equally at risk, and that's worth saying plainly to avoid panic. Semgrep stresses that the application must run an affected version, use a Brotli-capable parser, have inflation enabled and expose a route where it's mounted. Strobes says Express 5 with body-parser 2.x decodes Brotli request bodies by default, so a single app.use(express.json) can put the decoder in front of anonymous traffic.
The path we find most uncomfortable is the one nobody monitors: responses your own code fetches. Node's built-in fetch decodes Brotli automatically, and Strobes says Python's urllib3, aiohttp and httpx do the same when a Brotli package is installed, even if your code never imports it. Webhooks, link previews, "import from URL," crawlers and AI agents that browse are all doors an outsider can walk through. Strobes also says no WAF will see this path. Vercel's WAF, per TuxCare, blocks the inbound route but not responses fetched from elsewhere.
Heroic patching doesn't scale; inventories do
The standard reaction is a weekend of frantic upgrades. For Node 22, 24 and 26 that works: the fix is, in TuxCare's words, boring. But TuxCare also warns that Node.js 20, 18 and older get nothing from upstream, and the estate you forgot about is exactly the part that bites. Then there's the restart trap: a running process keeps the old decoder in memory.
The timeline should worry us too. TuxCare, citing The Hacker News, says the fixing change entered Brotli's source in February 2026 but didn't ship in a security release until October 21. Strobes adds that nobody connected it to remote code execution until October. A public patch is a map, as one Medium author put it. Strobes reports public proofs of concept exist, and no exploitation in the wild had been reported as of October 22, per TuxCare. We'd treat that calm as temporary, not reassuring.
The same week brought PHP2Shell, which Semgrep describes as a flaw that has existed in PHP for over a decade, and Google Cloud says applications on PHP 7.4 remain vulnerable to it. Two runtime disclosures within a day of each other isn't proof that security collapsed; Semgrep itself says the broader trend has been building for years. But it does show how little time we have to figure out what we run.
Our verdict
Patch now, obviously. Then do the dull work that actually protects you: keep an inventory that goes below package manifests, covering runtimes, bundled native libraries, container base images, CI runners and every place your code fetches a URL someone else controls. Retire end-of-life runtimes instead of hoping. We expect the next decompression bug to arrive sooner or later, and the team that can answer "where do we run this?" in minutes will beat the team with the best patching heroics.
No topics yet: start the first one.
More stories
Anonymous AI shopping agents are a gift to fraudsters
Arkose Labs says 97.7% of legitimate agent sessions carry no verified ID. Agentic commerce can't scale on guesswork, and disclosure should stop being optional.
The patch era just went machine-speed, and quarterly cycles are dead
Two AI-found flaws in PHP sent governments and companies scrambling. The lesson isn't panic: patch pipelines built for human timelines no longer match how fast attackers move.
A root shell on a Samsung TV proves your living room is an unpatched PC
Smart TVs are long-lived networked Linux computers, and the root exploits piling up show why vendors should owe TV owners phone-style update promises.
Capcom's 11.7M-account breach shows gaming IDs are still treated as cheap
A breach of 11,774,247 CAPCOM ID records is not "just emails". Publishers that run account systems at this scale should answer to the standards of any consumer platform.



