HTTP2Shell (CVE-2026-111497) is a 9.2-CVSS Brotli decoder RCE hitting Node.js, Python, and Bun. Here's what's affected, which versions fix it, and how to patch fast.
Vamsi Tallapudi
Manager, Architect Technology at Cognizant
HTTP2Shell is the nickname for CVE-2026-111497, an out-of-bounds write in Google's Brotli decoder that lets an unauthenticated attacker crash a process, leak its memory, or run code on it, just by sending it a crafted Brotli-compressed payload. Node.js, Python's brotli and brotlicffi packages, and Bun all bundle the broken decoder, and fixes shipped between October 21 and 22, 2026.
It started life with a worse name. Node.js called it "Node2Shell" when it patched the bug on October 21. Within a day, researchers found the exact same decoder baked into Python packages, Bun, curl, Envoy, and a pile of other software, so the name grew to "HTTP2Shell" to cover the whole blast radius. Someone on Hacker News pointed out that this is a terrible name too, since the bug has nothing to do with the HTTP/2 protocol specifically: it's a Brotli bug that happens to show up most often in HTTP stacks because that's where Brotli compression lives. "Broccoli2Shell" got floated as a joke and somebody actually registered the domain. Naming aside, this is a real, critical vulnerability and if you run a Node.js, Python, or Bun service that touches Brotli-compressed data from the network, you need to care about it today.
Google's Brotli decoder (the reference C library almost everyone's language bindings wrap) mishandles what's called an "invalid block switch" in a compressed stream. Instead of treating it as a format error and bailing out, the streaming decoder treats it like a temporary input shortage and keeps appending attacker-supplied data to an internal buffer. That buffer isn't sized for it. The write runs past its bounds, corrupting adjacent memory.
Google's own CVE record scores this 9.2 on CVSS 4.0. GitHub's advisory feed scores the same bug 9.8 on the older CVSS 3.1 scale, and Red Hat rates it 8.1 and calls it "Important" rather than "Critical": three vendors, three numbers, which tells you something about how messy CVSS scoring gets once a bug spans a dozen ecosystems. Whatever number you land on, the practical read is the same: no authentication required, no user interaction required, just a malicious Brotli stream reaching a vulnerable decoder.
Here's the detail that should worry you more than the bug itself. OpenAI's security team found the root cause back in February 2026 and the fix landed quietly in Brotli's source at the time. Nobody flagged it as a security issue. It sat there for eight months as a routine-looking code fix before someone connected it to a real, exploitable memory corruption bug and CVE-2026-111497 got assigned. That's eight months where anyone reading Brotli's commit history closely could have reverse-engineered the vulnerability before the rest of us knew it existed.
Probably, if you haven't patched since October 21. Every Node.js release line bundles Brotli, and the affected versions are:
| Node.js line | Vulnerable | Patched |
|---|---|---|
| 26.x | before 26.12.1 | 26.12.1 |
| 24.x | before 24.22.1 | 24.22.1 |
| 22.x | before 22.23.4 | 22.23.4 |
| 20.x and older | all versions | no fix (EOL) |
Node's security team bundled this fix into a release with nine other CVEs, including two TLS certificate hostname validation bypasses and a DNS NUL-byte truncation bug, plus a separate removal of trust for compromised eMudhra CA certificates that got blocked by Mozilla, Google, and Apple the same week. Ten issues in one release, and Brotli is the one that actually gets you popped.
What makes Node especially easy to hit is that you don't need to call Brotli yourself. Node's built-in fetch() auto-decompresses any response with Content-Encoding: br, so a server-side fetch to a malicious or compromised endpoint can trigger this. And if you're running Express 5 with the default body parser, body-parser 2.x decodes br, gzip, deflate, and zstd request bodies automatically. An attacker doesn't need you to opt into Brotli anywhere. They just need your server to accept Content-Encoding: br on an inbound request, which is the default, not an opt-in.
If you're still running Node 20 or earlier, there's no patch coming. That line is end-of-life and this is exactly the kind of bug that makes "I'll upgrade later" an expensive sentence. Move to 22.x or 24.x.
Python's brotli package on PyPI is vulnerable from 1.0.3 through 1.2.0, fixed in 1.2.1. The brotlicffi binding has its own vulnerable range, anything before 1.2.1.0, fixed in 1.2.1.0. GitHub's advisory for the Python packages (GHSA-9v8h-qqgm-4m35) landed about a day after Node's disclosure, and it hits the same code path: anything that calls requests with Brotli support installed, or decompresses Brotli responses directly, is exposed.
Bun bundled a vulnerable Brotli decoder in every release from 1.0.21 through 1.4.3. Version 1.4.4 bumps the bundled library to Brotli 1.2.1 and fixes it. If you've shipped a standalone executable with bun build --compile, patching your dev machine isn't enough: you need to rebuild that binary, because it has the old decoder baked in statically.
This is the part that turned "Node2Shell" into "HTTP2Shell." Because almost everyone wraps the same upstream Google Brotli C library instead of writing their own decoder, the bug shows up anywhere that library got linked in:
One clean exception: Apache's mod_brotli only encodes, it never decodes, so it's not affected. That's a useful reminder that the dangerous half of this bug is decompression, not compression. A server that only compresses its own outgoing responses was never at risk.
brotli to 1.2.1 and brotlicffi to 1.2.1.0.bun build --compile executables, Python wheels you built yourself, compiled binaries that vendor the C library.Content-Encoding: br at your WAF, load balancer, or reverse proxy until you can roll out the real fix. It's a blunt mitigation (you lose Brotli's bandwidth savings temporarily), but it closes the door faster than a coordinated rollout across every service that touches the vulnerable decoder.Don't forget the client side of this. If your server makes outbound fetch() calls or HTTP requests to third-party APIs, and one of those gets compromised or MITM'd on an unencrypted connection, a malicious Brotli response coming back at you is just as dangerous as a malicious request coming in.
Not that anyone's confirmed, as of October 25, 2026. It's not in CISA's Known Exploited Vulnerabilities catalog, and Node's own security team said they had no reports of in-the-wild exploitation or public proof-of-concept at release time. That said, Imperva's Red Team reported reproducing a working lab exploit: crafted Brotli data that caused a file to appear on disk that the target application had no code to create, meaning code carried inside the compressed stream executed inside the process. That's about as concrete a "yes, this is really RCE and not just a theoretical memory corruption bug" as you're going to get before someone weaponizes it for real.
I wouldn't treat "no confirmed exploitation yet" as a reason to wait. A pre-auth RCE in a compression library that half the internet's HTTP stack depends on, sitting in a release with a published fix and a catchy name, is exactly the kind of bug that goes from "theoretical" to "mass-scanned" within a week of disclosure. We've watched this pattern before with the LiteLLM supply-chain backdoor and the OpenCode breach: the gap between disclosure and someone building a scanner for it keeps shrinking, not growing.
If you run anything that decompresses network data you don't fully control (and if you're running Node, Python, or Bun in production, you almost certainly do), patch this one today, not next sprint. The CVSS score arguments and the naming drama are noise. The signal is: one memory bug in one shared library, baked into the default behavior of half the HTTP tooling people reach for, patched eight months after someone already found it. That's not a reason to panic. It's a reason to stop treating "update the runtime" as a task you schedule for later.
New AI tools, automation workflows, and course drops — straight to your inbox. Join 2,400+ builders.
Block's Dessa is a full-duplex voice AI trained only on human speech, no text. Here's what's verified, what it can't do yet, and why developers should care.
Reason Network is a free, open-source daemon that lets Claude Code, Codex, Cursor and other agents message each other across machines, peer-to-peer and encrypted.
leanrea is an 8 KB Claude Code skill claiming to replace REA's 207-tool MCP server: 38% faster, 35% cheaper, near-identical accuracy. Here's what checks out.
Comments