TL;DR
- Node2Shell is CVE-2026-111497, an out-of-bounds write in the Brotli decoder that Node.js bundles. Malformed compressed input can crash the process, leak its memory or lead to remote code execution 1.
- It is reachable when an application decompresses Brotli data an attacker controls. Express 5, body-parser 2 and Koa's body parser do this for request bodies before any route runs, and Node's built-in
fetch()does it for responses 45. - Fixed in Node.js 22.23.4, 24.22.1 and 26.12.1, released 21 October 2026 1. Node.js 20 and older, 23 and 25 are end of life and get no upstream fix 6.
- The bug is in Google's Brotli library itself (fixed in 1.0.10, 1.1.1 and 1.2.1), so Bun, Python's Brotli packages, Envoy, Istio and other software that embeds it need their own updates 312.
- CISA added it to its Known Exploited Vulnerabilities catalog on 27 October 2026; US federal agencies must fix it by 10 November 2.
Overview
This write-up is based on the Node.js security advisory, CISA's catalog entry, distribution advisories and the research listed at the end. It explains how the bug works and who is exposed. It deliberately leaves out exploitation details, payloads and request formats.
On 21 October 2026 Node.js shipped security releases for its 22, 24 and 26 lines. The most serious fix, CVE-2026-111497, is in the Brotli decoder bundled with Node.js 1. The same day, Google released Brotli 1.0.10, 1.1.1 and 1.2.1 with the fix 12. The bug circulates as Node2Shell, and also as HTTP2Shell and Broccoli2Shell 4.
CISA lists it under Google's Brotli rather than Node.js, as an unchecked return value (CWE-252) that leads to an out-of-bounds write (CWE-787) 2. Ratings differ by vendor: CVSS v4.0 9.2 (Critical) 7; Node.js rates it High 1; Red Hat rates it Important (CVSS v3.1 8.1), scoring attack complexity as high 8.
It was reported by Khai Tran and Sylvie Mayer of OpenAI Codex Security and fixed in Node.js by Matteo Collina and Antoine du Hamel 13. The same Node.js release fixed nine other vulnerabilities, including two high-severity TLS hostname-verification bypasses and a DNS name-truncation bug, so upgrading closes those too 1.
Background: Brotli in Node.js
Brotli is a compression format that web servers and browsers use alongside gzip. Node.js ships its own copy of Google's Brotli library and exposes it through node:zlib, for example zlib.brotliDecompress() and zlib.createBrotliDecompress() 19.
Some Linux distributions build Node.js against the system's shared Brotli library instead of the bundled copy. Debian, Ubuntu 22.04 and later, and parts of Red Hat Enterprise Linux do this, and for those builds the fix is an update to the system libbrotli package rather than to Node.js 7810.
The bug
Node.js describes the flaw this way: an invalid block switch in the compressed stream was reported as a temporary need for more input instead of a permanent format error. The streaming decoder therefore kept appending input bytes to an eight-byte internal buffer and wrote past its end 1. CISA's description, an unchecked return value, is the same mistake seen from the code: the error condition was not handled as an error 2.
The flawed code dates back to Brotli 1.0.3, released in March 2018, so every Brotli release from 1.0.3 to 1.2.0 is affected 34. ELLIO reports that the fix first landed on Brotli's public development branch without a release or advisory 4.
The consequences depend on what the overwritten memory holds: a crash, disclosure of process memory, or, in the worst case, remote code execution with the privileges of the Node.js process 12.
Who is exposed
The vulnerable code only runs when something decompresses Brotli data. Node.js puts it plainly: an attacker must be able to supply Brotli data that the application decompresses with node:zlib 1. In practice that happens in more places than application code suggests, because frameworks and HTTP clients do it automatically 345:
- Request bodies. Express 5 (through
express.json()orexpress.raw()), body-parser 2 and Koa with@koa/bodyparserdecompress request bodies sent withContent-Encoding: brbefore any route handler runs, and any client can send one 45. - Responses your app fetches. Node's built-in
fetch()decompresses Brotli responses automatically, as do axios, got and SuperAgent, and server-side fetches in frameworks such as Next.js. A server you call, including one behind a webhook or user-supplied URL, can send a malicious response 45. - Direct calls. Any code that passes untrusted data to the
node:zlibBrotli functions 45.
Beyond Node.js. Because the bug is in Brotli itself, other software is affected too 34:
- Bun 1.0.21 to 1.4.3 (fixed in 1.4.4). Executables built with
bun build --compilestay affected until rebuilt 34. - Python's
Brotli(fixed in 1.2.1) andbrotlicffi(1.2.1.0). HTTP clients such as urllib3, requests, httpx, aiohttp and Scrapy decode Brotli responses when the package is installed 34. - Envoy (fixed in 1.36.12, 1.37.8, 1.38.6, 1.39.3 and 1.40.0) where its Brotli decompressor is configured, and Istio (1.29.9, 1.30.6, 1.31.2) 3.
- The Go port
andybalholm/brotlibefore v1.2.7 3. - Firefox and Thunderbird embed their own copies; Red Hat lists them among affected packages 9.
Wiz reports that 91% of cloud environments have resources vulnerable to CVE-2026-111497 and 82% have publicly exposed Node.js instances 3. Our live counter tracks how many Node.js services are visible on the internet; Node.js doesn't reveal its version, so it measures exposure rather than patch status.
Exploitation status
CISA added CVE-2026-111497 to its Known Exploited Vulnerabilities catalog on 27 October 2026, which means it has evidence of exploitation in the wild. US federal civilian agencies must apply the fix by 10 November 2.
ELLIO reports seeing a public exposure checker, which identifies itself as node2shell-check, send short bursts of Brotli-encoded requests to find hosts that decompress Brotli at all, and exploit traffic from a different source the day after. On 26 October at 15:08 UTC its sensors recorded a Brotli-encoded request body of about 23 MB. ELLIO advises treating the flaw as exploited 4.
Reliability is debated. Red Hat says attack complexity is high and notes that no public, reliable remote code execution proof of concept exists 8. Wiz credits Ron Masas of Imperva's red team with demonstrating exploitability 3.
Timeline
| Date | Event | Source |
|---|---|---|
| Mar 2018 | The flawed code ships in Brotli 1.0.3 | 4 |
| Oct 21, 2026 | Node.js releases 22.23.4, 24.22.1 and 26.12.1; Google releases Brotli 1.0.10, 1.1.1 and 1.2.1 | 112 |
| Oct 22 | Bun 1.4.4 ships the fix | 3 |
| Oct 24 | Amazon Linux 2023 fixes brotli and nodejs24 | 11 |
| Oct 26 | Ubuntu publishes USN-8956-1 for its Brotli packages; ELLIO records a 23 MB Brotli-encoded request at 15:08 UTC | 74 |
| Oct 27 | CISA adds CVE-2026-111497 to its Known Exploited Vulnerabilities catalog (due 10 Nov) | 2 |
Detection
- inbound requests with
Content-Encoding: brto services that don't need them; - the user agent
node2shell-check, which belongs to a public exposure scanner; - unusually large Brotli-encoded request bodies;
- repeated crashes or restarts of Node.js workers. ELLIO points out that a run of decoder crashes is also a possible data leak wherever core dumps are written 4.
Read-only checks you can run now
These only read versions, packages and logs.
# Node.js version: fixed in 22.23.4, 24.22.1, 26.12.1 or later
node -v
# Does this Node.js use the system Brotli library? (no output = bundled copy)
ldd "$(command -v node)" | grep -i brotli
# System Brotli package version (Debian/Ubuntu, then RHEL/Fedora/Amazon)
dpkg -l 'libbrotli*' 2>/dev/null | awk '/^ii/ {print $2, $3}'
rpm -q brotli 2>/dev/null
# Frameworks that decompress Brotli request bodies (look for express 5 / body-parser 2)
npm ls express body-parser @koa/bodyparser 2>/dev/null
# Direct Brotli decompression in your code
grep -rnE "brotliDecompress|createBrotliDecompress" --include='*.js' --include='*.ts' --exclude-dir=node_modules .
# The public exposure scanner in web server logs
sudo grep -h "node2shell-check" /var/log/nginx/access.log* /var/log/apache2/*access.log* 2>/dev/null | tail -n 20process.versions.brotli doesn't prove you're fixed: the fixed Node.js builds still report the same Brotli version as before. Check the Node.js version instead.
Mitigation
Patch. Upgrade to Node.js 22.23.4, 24.22.1, 26.12.1 or later 1. If your Node.js uses the system Brotli library, update that package instead (Debian DLA-4855-1 and DSA-6582-1, Ubuntu USN-8956-1/-2, Amazon ALAS2023-2026-3334) 10711. Then restart every Node.js process, and rebuild and redeploy containers, because running processes keep the old code 3. Commands for each platform are in our patch guide.
End-of-life Node.js. Node.js 20 reached end of life on 30 April 2026, and it and older lines have no upstream fix. Move to Node.js 22 or 24; HeroDevs is preparing paid fixed builds for 20.x and then 18.x 6.
Stopgaps, which reduce exposure but do not replace patching 39:
Sources
- Node.js: Wednesday, October 21, 2026 Security Releases
- CISA: Known Exploited Vulnerabilities Catalog (CVE-2026-111497 added 27 October 2026)
- Wiz: Broccoli2shell, everything you need to know about the critical Brotli decoder vulnerability
- ELLIO: Node2Shell (CVE-2026-111497) aka HTTP2Shell and Broccoli2Shell, RCE analysis
- Aikido: Node2Shell, Node.js Brotli vulnerability allows remote code execution, and the fix
- HeroDevs: CVE-2026-111497 (Node2Shell), end-of-life Node.js
- Ubuntu: CVE-2026-111497
- Red Hat: CVE-2026-111497
- Red Hat: RHSB-2026-015, Brotli decoder vulnerability
- Debian security tracker: CVE-2026-111497
- Amazon Linux Security Center: CVE-2026-111497
- google/brotli: v1.2.1 release (also v1.1.1 and v1.0.10, 21 October 2026)