Node2Shell CVE-2026-111497: Node.js Brotli RCE and Fixes

Node2Shell is the nickname for CVE-2026-111497, an out-of-bounds write in the Brotli decoder that ships inside Node.js. A crafted Brotli stream can crash a Node.js process, leak its memory, or in some setups run attacker code. Node.js fixed it on October 21, 2026 in versions 22.23.4, 24.22.1 and 26.12.1, and credits the find to OpenAI's Codex Security agent. If your service decompresses Brotli data it does not control, update now.
The bug is in Google's Brotli library, not in Node.js's own code, so Bun, Envoy and Python's Brotli packages needed their own fixes too. A day after the release, Imperva ran code on an unmodified official Node.js image.
Key takeaways
- Node.js 22.23.4, 24.22.1 and 26.12.1 fix the bug, per the Node.js October 2026 security release. End-of-life lines such as 25.x and 20.x get no fix.
- Google, which issued the CVE, scores it 9.2 on CVSS v4.0 in the CVE record. Node.js rates it High.
- Node.js credits the find to "OpenAI Codex Security (Khai Tran and Sylvie Mayer)". Envoy's advisory credits OpenAI Security Research.
- Public proof-of-concept code exists. Imperva achieved code execution on Node.js 24.22.0 for Linux arm64. No in-the-wild attacks had been confirmed as of October 24.
- The most exposed services are apps that call
fetch()against untrusted servers, Express 5 with body-parser 2, and any code that runsnode:zlibBrotli decompression on outside input.
What is Node2Shell (CVE-2026-111497)?
CVE-2026-111497 is a memory-safety bug in the Brotli decompressor (c/dec/decode.c) in Google Brotli versions 1.0.3 through 1.2.0. The CVE record describes it as a buffer overflow that lets "a remote unauthenticated attacker" corrupt decoder memory, disclose memory contents, cause a denial of service, "or potentially execute arbitrary code using a crafted Brotli-compressed stream."
Brotli is the compression format behind the br value in the HTTP Content-Encoding header. Browsers, CDNs and servers use it widely, and Node.js bundles its own copy of the decoder to support node:zlib.
The Node.js advisory explains the root cause in one sentence: "An invalid block switch was reported as a temporary need for more input instead of a permanent format error, so the streaming decoder kept appending input bytes to an eight-byte internal buffer." In plain terms, the decoder hit an impossible instruction in the compressed data, mistook it for "wait for more bytes," and kept writing past the end of a tiny buffer. The CVE record files it under CWE-787 (out-of-bounds write) and CWE-252 (unchecked return value).
Google published fixed Brotli releases 1.0.10, 1.1.1 and 1.2.1 on GitHub on October 21. The fix makes the decoder return a format error for that invalid transition.
Why it is called Node2Shell
The name comes from Imperva's research post, "Node2Shell: From Brotli Data to Remote Code Execution," published October 22. It follows the "-2Shell" naming used for other recent remote code execution bugs, including PHP2Shell. "Shell" means an attacker could get a command shell on the server, which so far has been shown in only one tested setup.

Which versions are affected and fixed?
Every release on the supported 22.x, 24.x and 26.x lines before the fixed version is affected. So is every end-of-life line, because Node.js says EOL versions "are always affected" when a security release ships.
| Product | Vulnerable | Fixed | Source |
|---|---|---|---|
| Node.js 26.x (Current) | before 26.12.1 | 26.12.1 | Node.js advisory |
| Node.js 24.x (LTS) | before 24.22.1 | 24.22.1 | Node.js advisory |
| Node.js 22.x (LTS) | before 22.23.4 | 22.23.4 | Node.js advisory |
| Node.js 25.x, 20.x and older | all | no fix (end-of-life) | Node.js advisory |
| Google Brotli (C library) | 1.0.3 to 1.2.0 | 1.0.10, 1.1.1, 1.2.1 | CVE record |
| Bun | 1.4.3 and earlier | 1.4.4 | Bun v1.4.4 notes |
| Envoy (Brotli decompressor configured) | v1.39.2, v1.38.5, v1.37.7, v1.36.11 | v1.40.0, v1.39.3, v1.38.6, v1.37.8, v1.36.12 | GHSA-3wvj-j6qm-62mr |
Python Brotli / brotlicffi | 1.2.0 and earlier | 1.2.1 / 1.2.1.0 | PyPI: Brotli, PyPI: brotlicffi |
Debian brotli package | bookworm 1.0.9-2, trixie 1.1.0-2 | 1.0.9-2+deb12u1, 1.1.0-2+deb13u1 | Debian tracker |
The npm package named brotli is unrelated, so updating it does nothing; the vulnerable code lives in the Node.js runtime binary. Debian is a special case: its own nodejs package links the system Brotli library, so on Debian the fix arrives through the brotli package rather than a new Node.js version number.
The same Node.js release fixed nine other CVEs, including three more rated High: a DNS name truncation bug (CVE-2026-105482) and two TLS hostname-check bypasses (CVE-2026-105483 and CVE-2026-106069).
Who is actually exposed?
You are exposed if attacker-influenced Brotli bytes reach the decoder. Running a vulnerable Node.js version alone is not enough. According to the Node.js advisory, "An attacker who can supply Brotli data that an application decompresses with node:zlib" can corrupt process memory. In practice, that data arrives through three main routes:
- Outbound
fetch(): Node.js's built-infetch()decodes responses sent withContent-Encoding: br. A service that fetches user-supplied URLs (link previews, webhooks, scrapers, AI agents browsing the web) can receive a malicious response. - Inbound request bodies: the body-parser README states that all its parsers "support automatic inflation of
gzip,br(brotli),deflate", and theinflateoption defaults totrue. Express 5 uses body-parser 2, so a public Express 5 API decodes Brotli bodies by default. Sysdig also lists Koa (via co-body) and Fastify with@fastify/compress. - Direct
node:zlibcalls: any code that runsbrotliDecompress,brotliDecompressSyncorcreateBrotliDecompresson uploaded files or queue messages.
Internal tools that only decompress their own data are lower priority. They still need the update, because Brotli input can come from places teams forget, such as a third-party API response.
How OpenAI's Codex Security found the bug
Node.js credits the report to "OpenAI Codex Security (Khai Tran and Sylvie Mayer)." Codex Security is OpenAI's application-security agent, which launched as a research preview to find, validate and fix vulnerabilities in codebases. Envoy's advisory for the same CVE credits "OpenAI Security Research."
The Node.js fix shipped on October 21, the same day as the fix for PHP2Shell, another set of old bugs that AI-assisted audits turned into working exploits. In both cases AI tools were reading old, widely shared C code, and every project that bundled that code had to ship its own fix. The LiteLLM supply-chain compromise, also on October 21, was a different kind of attack, but it points to the same risk: dependencies you did not know you had.
The timeline was short:
| Date (2026) | Event |
|---|---|
| October 16 | Google reserves CVE-2026-111497 |
| October 21 | Google publishes Brotli 1.0.10, 1.1.1 and 1.2.1; Node.js ships 22.23.4, 24.22.1 and 26.12.1 |
| October 22 | CVE record goes public; first public proof of concept; Imperva reports code execution; Bun 1.4.4, Python Brotli 1.2.1 and brotlicffi 1.2.1.0 ship |
| October 23 | Envoy publishes GHSA-3wvj-j6qm-62mr |
| October 24 | Sysdig reports no confirmed in-the-wild exploitation |
How dangerous is it in practice?
Crashing a process is easy; running code is hard. Imperva's Ron Masas reports code execution on the official Node.js 24.22.0 Linux arm64 image, delivered both as a fetched HTTP response and as an Express request body. He also writes that it "took multiple attempts in our setup." Imperva has not published its exploit, and Node.js 24.22.1 rejected the same input.
The first public proof of concept, per HeroDevs' summary, reached code execution only on a deliberately weakened test build. On a standard build it produced a crash and a limited memory read. Nobody has publicly shown code execution on Bun, Envoy or the Python packages.
A crash alone still hurts. One malformed request that kills a Node.js worker is a cheap denial-of-service attack against any public Express 5 API. A memory leak can also expose tokens or keys held in the process.
How to patch Node2Shell and verify the fix
- Upgrade the runtime to 22.23.4, 24.22.1 or 26.12.1. These are patch releases with no API changes.
- Check what is actually running. Run
node --versioninside each running container, not just in your Dockerfile. Sysdig warns that a floating tag likenode:24can keep an old build if you rebuild from a cached image, so pull the base image again before rebuilding. - Rebuild everything that embeds Node.js, including container images, serverless bundles, CI runners and single-executable apps, then restart the processes.
- Move off end-of-life lines. Node.js 20, 25 and older will not get an upstream fix, so move them to 22 or 24, or use a commercial extended-support build.
- Patch the neighbors: update Bun to 1.4.4, Envoy to the fixed release in its advisory, Python
Brotlito 1.2.1, and distrobrotlipackages. - While the rollout runs, Imperva suggests temporarily limiting untrusted Brotli traffic on exposed paths. With body-parser you can set the
inflateoption tofalse, which rejects all compressed request bodies (gzip included), so test it against real clients first. - Watch for crashes. Imperva and Sysdig both treat unexpected Node.js exits and decoder errors as leads to investigate, not proof of attack. A crash followed by a new process running in the same container is the pattern to alert on.
FAQ
Is Node2Shell being exploited in the wild?
As of October 24, 2026, Sysdig reported no confirmed in-the-wild exploitation, and CISA had not added CVE-2026-111497 to its Known Exploited Vulnerabilities catalog as of October 23. Public proof-of-concept code exists, and Imperva showed code execution on one official Node.js build, so patch now rather than waiting for a KEV listing.
Does updating the npm "brotli" package fix CVE-2026-111497?
No. The vulnerable decoder is compiled into the Node.js runtime. Only Node.js 22.23.4, 24.22.1, 26.12.1 or later (or, on Debian, the patched system brotli package) remove the flaw.
I use Node.js 20. What should I do?
Node.js 20 is end-of-life and will not receive an upstream fix for CVE-2026-111497. Upgrade to Node.js 22.23.4 or 24.22.1. If you cannot upgrade soon, block or disable Brotli decoding of untrusted input and consider a commercial extended-support build.
Are browsers affected?
The CVE record and the advisories cited here cover the Brotli C library and the projects that bundle it, such as Node.js, Bun, Envoy and Python packages. None of them names a browser, so check your browser vendor's own release notes rather than assuming either way.
Who discovered Node2Shell?
Node.js credits OpenAI Codex Security, with researchers Khai Tran and Sylvie Mayer. Imperva later named the bug "Node2Shell" and demonstrated code execution.
Sources
- Node.js: October 21, 2026 Security Releases
- CVE-2026-111497 record (cve.org)
- Google Brotli v1.2.1 release
- Imperva: Node2Shell, From Brotli Data to Remote Code Execution
- Envoy advisory GHSA-3wvj-j6qm-62mr
- Bun v1.4.4 release notes
- Debian security tracker: CVE-2026-111497
- Sysdig: Detecting the Node.js Brotli RCE
- HeroDevs: CVE-2026-111497 (Node2Shell)
- expressjs/body-parser README
- PyPI: Brotli and PyPI: brotlicffi