Vulnerability
Node2Shell Explained: The Brotli Bug Behind Node.js RCE
A flaw in Google's Brotli decoder lets a crafted compressed request or response crash, leak or take over a Node.js process. This is how it was found, named, patched and exploited, and what to fix first.
6 min read
On October 21, 2026, the Node.js project shipped security releases for its 22.x, 24.x and 26.x lines. One fix, CVE-2026-111497, is a remote code execution bug in the Brotli decoder that Node.js bundles. The community named it Node2Shell.
What is Node2Shell?
Node2Shell is an out-of-bounds write in Google's Brotli C decoder, versions 1.0.3 through 1.2.0. Google scores it CVSS 4.0 9.2 (Critical), while the Node.js project rates its bundled copy High. NVD adds a CVSS 3.1 score of 9.8, and Microsoft scores the .NET instance 8.1.
The name is slightly misleading. The flaw sits in a shared library, so every product that bundles or links a vulnerable copy inherits it. It is also tracked as Broccoli2Shell, HTTP2Shell and Brotli2Shell.
How the bug works
A Brotli stream can signal a switch between block types. When the stream declares an invalid switch, the vulnerable decoder reported it as a temporary need for more input instead of a permanent format error. The streaming decoder then kept appending input bytes to an eight-byte internal buffer and wrote past its end.
Google's record lists two weaknesses: CWE-252 (unchecked return value) is the bug, and CWE-787 (out-of-bounds write) is its effect. The upstream fix makes the decoder return a dedicated format error for the invalid block switch, so malformed streams are rejected.
The story so far
2018: the bug ships. ELLIO reports the flaw arrived with Brotli 1.0.3 in March 2018.
February 2026: a quiet fix. ELLIO says a fix was written on February 27, 2026 and landed in the public master branch with no release or advisory, where it stayed for about eight months. Treat this as one vendor's account.
Before October 21: private report. The Node.js advisory credits OpenAI Codex Security researchers Khai Tran and Sylvie Mayer for reporting it, and Matteo Collina and Antoine du Hamel for the fix. OpenAI's Patch the Planet page lists Node.js, Bun, Envoy and Istio among affected projects.
October 21: patch day. Node.js released 22.23.4, 24.22.1 and 26.12.1. Google Brotli published 1.0.10, 1.1.1 and 1.2.1 the same day, and the 1.2.1 changelog lists the CVE. Researchers noted the 1.2.1 release notes did not mention the vulnerability beyond the CVE line.
October 22: the name and the first lab RCE. Imperva Red Team demonstrated code execution against the official Node.js 24.22.0 Linux arm64 image and coined "Node2Shell". NVD published the record the same day.
October 23: a wider name. Researchers began using "HTTP2Shell" as evidence emerged that other ecosystems were affected.
October 25: Microsoft patches .NET. Microsoft shipped fixes for .NET, Visual Studio and PowerShell.
October 27: CISA KEV. CISA added CVE-2026-111497 as "Google Brotli Unchecked Return Value Vulnerability". The federal due date is November 10, 2026.
How attackers can reach it
Node.js is only vulnerable when attacker-controlled Brotli data reaches the decoder. Akamai lists three paths:
- Request bodies: Express 5 and body-parser 2 decompress
Content-Encoding: brrequest bodies by default, because theinflateoption defaults to true, so any client can send one. - Fetched responses: the built-in
fetch()decompresses Brotli responses automatically, so a malicious or compromised server can target the client. - Direct zlib calls: applications passing untrusted input to
zlib.brotliDecompress()orzlib.createBrotliDecompress().
A bare Node.js HTTP server does not decode incoming Brotli bodies on its own. Semgrep also lists Koa body parsers and Fastify's @fastify/compress plugin as confirmed entry points. Next.js image optimization fetches remote images, which is why OpenAI's guidance suggests disabling it as a stopgap.[12][9]
What exploitation looks like
The honest picture has three layers.
| Layer | What is public |
|---|---|
| Lab RCE | Imperva ran code on Node.js 24.22.0 arm64 via fetch() and Express 5 bodies; it did not work on every attempt |
| Independent repro | ELLIO reproduced a shell on x86-64 against four targets on the same build (plain node:http, the official slim image as root, Express 5.3.0, Koa 3) |
| In the wild | ELLIO recorded a scanner sweeping hosts for Brotli decoding, then exploit traffic carrying the public exploit on October 26 |
| Official listing | CISA cites evidence of active exploitation but does not describe it |
ELLIO also describes one attacker payload as a first-generation attempt that failed in its lab: it scored zero hits in 50 attempts against a vulnerable build. A news summary notes that neither BleepingComputer nor SecurityWeek names a production victim or confirms code execution in a live service. Censys likewise says public reports show no reliable code execution across builds and platforms, and that demonstrated outcomes are mostly crashes and denial of service.
Why it is not "Log4Shell for Node"
The working exploit is tied to specific builds. ELLIO found the offset for 24.22.0 worked on all four targets, while the same value gave nothing in 10,000 attempts against 22.23.3 and 26.12.0. Failed attempts usually crash the worker, so many attacks present as denial of service, and restart supervisors give attackers repeated tries.
Defenders should still move fast. Public proofs of concept exist, and ELLIO expects per-build, version-targeted waves. EPSS was reported at about 83% on October 29.
Not just Node.js
JFrog calls the wider problem "Brotli2Shell" and reproduced a remote crash in ClickHouse, memory corruption in FFmpeg through libjxl, a .NET runtime crash and an infinite loop in Apache Arrow. Semgrep reports 433 package entries across 12 ecosystems that bundle the decoder, with 71% having no fix available at the time.
Other fixed releases include Bun 1.4.4, Python Brotli 1.2.1, brotlicffi 1.2.1.0, Envoy 1.40.0 and its supported branches, and Istio 1.29.9, 1.30.6 and 1.31.2. Palo Alto Networks confirmed impact on some PAN-OS deployments and its Prisma Cloud Application Security Transporter Client.
How to fix it
- Upgrade Node.js to 22.23.4, 24.22.1 or 26.12.1, or later. The Node.js advisory offers no workaround.
- Replace end-of-life lines. Node.js 20, 23 and 25 get no fix.
- Do not trust the version string. ELLIO says Node.js cherry-picked the fix without bumping the bundled version, so
process.versions.brotlireports 1.2.0 on both patched and vulnerable builds. Check the Node.js release version instead.[10] - Rebuild containers. A Dockerfile pinned to 24.22.0 keeps shipping the vulnerable build until you change it. A patched runtime does not reach decoders baked into other images or compiled binaries.
- Patch other copies. Distribution
brotlipackages, Python wheels, .NET, Bun and anybun build --compileexecutable need their own updates. - Use a temporary guard if you cannot patch. Reject
Content-Encoding: brbefore any parser runs, or set body-parserinflate: false(which rejects all compressed bodies). AWS WAF and Imperva rules can block the header, but request-side rules do not cover responses from upstream services. - Hunt for crashes. Imperva says unexpected exits during decompression may help prioritize investigation but are not reliable proof of exploitation on their own. ELLIO warns that core dumps from forced crashes can contain other users' credentials.
Cloud notes
On AWS Lambda, the managed service is not affected but Node.js and .NET runtimes are. For container images, rebuild from the updated base image; for ZIP packages, a zero-change update is not enough, so change code or configuration to pick up the patched runtime. As of the bulletin, Node.js ZIP phase 2 was scheduled for October 30, 2026. Elastic Beanstalk Node.js platform version 6.11.12 shipped on October 22.
Related: PHP2Shell
Node2Shell arrived a day after PHP2Shell, a separate pair of PHP flaws fixed the same day. Censys says that naming association likely amplified attention, but the two differ: PHP2Shell affects PHP installations serving requests, while this flaw needs an application to pass attacker-controlled Brotli to a vulnerable decoder.
How Codebumble can help
We audit Node.js stacks, containers and dependencies for hidden Brotli exposure. Contact us for a quick review.
Sources
- Node.js October 2026 security releases
- Imperva: From Brotli Data to Remote Code Execution
- Akamai: Inside Node2Shell
- ELLIO: RCE on stock Node.js builds
- JFrog: Brotli2Shell
- Semgrep: Broccoli2Shell package list
- Censys advisory
- CISA KEV alert
- AWS security bulletin
- OpenAI Patch the Planet: Brotli
Last updated: October 30, 2026.