Node2Shell is the name researchers and social media use for CVE-2026-111497, a flaw in the Brotli decoder inside Node.js. Node.js fixed it on 21 October 2026 in versions 22.23.4, 24.22.1 and 26.12.1. The Node.js advisory rates it high and says it permits remote code execution. The CVE record from Google rates it 9.2 on CVSS 4.0, which is critical. Node.js itself does not use the name.
This post joins the Node.js advisory, the fix from the Brotli project, the CVE record and the first public statements. It marks what is confirmed and what is only reported. It sits next to our PHP2Shell analysis, because both fixes landed on the same day. It also sits next to the eMudhra CA key compromise, which changed Node.js’s certificate list in the same release.
Last updated: 22 October 2026, 20:30 UTC (GitHub proof-of-concept section added). We update this post when Node.js, the Brotli project or national CERTs publish new facts.
What Is Node2Shell?
Brotli is a compression format. Web servers and clients use it to shrink data in transit. The Brotli decoder is the code that unpacks it, and Node.js ships a copy of that code.
The CVE record, written by Google as the CVE numbering authority, describes a buffer overflow in the decoder file c/dec/decode.c. It says a remote attacker with no login can use a crafted Brotli stream. The attacker could corrupt memory next to the decoder state, read sensitive memory, crash the process or possibly run code. The record lists the weakness types out-of-bounds write (CWE-787) and unchecked return value (CWE-252).
The Node.js advisory credits OpenAI Codex Security, with Khai Tran and Sylvie Mayer, for reporting the flaw. It lists the issue as high and says it affects Node.js 26.x, 24.x and 22.x. The release notes list two changes for it: a Brotli code update taken from the upstream project, and a change that exposes a new Brotli decoder error code.
- Crafted Brotli dataThe attacker sends compressed data to an app that decodes it, in a request body or a fetched response
- Decoder reads the streamNode.js unpacks the data with its built-in Brotli decoder
- Out-of-bounds writeBad input makes the decoder write past its buffer and corrupt nearby memory
- ImpactMemory leak, crash or command execution with the permissions of the Node.js process
The steps above restate the CVE record and the Vercel bulletin. Vercel says researchers showed memory disclosure and command execution in the Node.js process on unpatched 22.x, 24.x and 26.x. The CVSS 4.0 vector in the CVE record has network access, low complexity and no privileges or user action. It also marks an attack requirement as present, which fits the fact that the app has to decode the attacker’s data.
Which Node.js Versions Are Fixed?
Node.js published v22.23.4, v24.22.1 and v26.12.1 on 21 October 2026 at 10:38 UTC. The advisory also says: “End-of-Life versions are always affected when a security release occurs.”
| Node.js line | End of life (Node.js schedule) | Fixed version |
|---|---|---|
| 26.x | 30 Apr 2029 | 26.12.1 |
| 24.x | 30 Apr 2028 | 24.22.1 |
| 22.x | 30 Apr 2027 | 22.23.4 |
| 20.x | 30 Apr 2026, already ended | No fix published |
| 25.x | 1 Jun 2026, already ended | No fix published |
| 18.x and older | Ended (18.x on 30 Apr 2025) | No fix published |
The end-of-life dates come from the Node.js release schedule file. Vercel says Node.js 20 “will not receive this fix”, and tells projects on it to move to 22.x or 24.x. If you run a version from the last three rows, treat it as affected and plan an upgrade. We found no published test that shows those older lines are exploitable, so this is the Node.js rule, not a measurement.
Who Is Really Exposed?
Vercel puts it this way: Node.js does not decode Brotli data on its own. An app is exposed when its code, or a library it uses, decompresses Brotli data that an attacker controls. That can be a request body or a response the app fetches. Three routes matter most, and we checked all three in the public source code.
| Route | Does it reach the Brotli decoder? | What the source shows |
|---|---|---|
Express 5 with express.json() |
Yes, by default | Express 5.3.0 depends on body-parser ^2.3.0. body-parser 2.x decodes br, gzip, deflate and zstd bodies, and its inflate option defaults to true. |
Express 4 with express.json() |
Not through body-parser | Express 4.21.2 to 4.22.3 depend on body-parser 1.20.x. Its 1.x code handles only deflate and gzip and answers 415 to other encodings. |
Server-side fetch() |
Yes, for Brotli responses | The undici code behind Node.js fetch adds a Brotli decompressor when a response says br. Vercel says only the runtime patch covers fetched responses. |
The first row is the one that worries people. The JSON parser runs for requests with a JSON content type. If such a request also says Content-Encoding: br, the body goes through Node’s Brotli decoder before your route code runs. Ron Masas, a researcher, wrote on X on 22 October that on a vulnerable runtime, “app.use(express.json()) is enough”. He says a single Brotli request then exposes the server to code execution. That matches what the source code does for Express 5.
The second row is a reading of the code, not a promise. Other middleware, frameworks, reverse proxies and your own code may still decode Brotli. Vercel also notes that self-hosted Next.js image optimization does not block Brotli responses. For the Next.js side of this week, see our Next.js and Node.js security updates guide.
Is Node2Shell Being Exploited?
As of 22 October at 19:57 UTC, we found no confirmed report of attacks. Three facts point different ways.
- Not in the KEV file. The CISA Known Exploited Vulnerabilities catalog we read does not list the CVE.
- CISA’s assessment. The CISA data attached to the CVE record lists exploitation “none”, automatable “no” and technical impact “total”.
- A researcher reproduced it. Ron Masas wrote that his team reproduced the flaw as pre-authentication RCE. The write-up he links is on Imperva’s site, which blocked our tools, so we rely on his public statement and not on the article.
Public proof-of-concept code is on GitHub, covered in the next section. Treat any file, token or “scanner” offered under the Node2Shell name as untrusted until a vendor or a CERT confirms it.
Is There a Public Node2Shell Exploit on GitHub?
Yes, proof-of-concept code is public, but it does not settle the remote code execution question. On 22 October at 20:28 UTC, a GitHub search for CVE-2026-111497 returned 11 repositories. The first appeared on 21 October at 15:47 UTC, about five hours after the Node.js fixes shipped. We read their descriptions. We did not run any of the code.
- Crash on stock Node.js. One lab sends two Brotli chunks over the network to a small service that uses the standard zlib API. Its authors report that the service goes down on Node.js 20.19.5, 22.23.3, 24.22.0 and 26.12.0. In their tests, the fixed 22.23.4, 24.22.1 and 26.12.1 reject the same input. The authors do not claim remote code execution.
- Code execution in a lab. Another team reports local command execution in three of three runs. It needed a Node.js build that loads an unfixed system Brotli library and a predictable memory layout, set with a Node.js flag or by turning off address randomization. The same team says blind remote code execution with randomization on did not work.
- A dissenting analysis. One researcher argues that no Brotli stream, valid or malformed, can reach the bad write, so the real impact is a denial of service. That is one analysis, not the view of Node.js or Google.
- Other repositories. One more lab with an Express app claims code execution in its title. The earliest repository says no public exploit exists and offers probes and a resource exhaustion test. The rest are version checkers, audit scripts and mitigation notes.
So public code reportedly crashes unpatched Node.js, and remote code execution is claimed but not shown in public code. That is enough reason to patch now. A crash can take down a service that decodes Brotli from users. Run any GitHub proof of concept only in an isolated lab, because exploit code from unknown accounts can hide malware. We do not link these repositories.
How Can You Check Your Exposure?
We know of no safe test for the flaw from Node.js or a CERT, so do not send exploit traffic to a server. You can check versions and code paths safely.
- List every Node.js runtimeInclude containers, CI runners, serverless functions, build servers and tools that ship their own Node.js.
- Read the versionRun node –version inside the real runtime or image. Compare with 22.23.4, 24.22.1 and 26.12.1, or newer.
- Rebuild imagesA base image tag can be old. Pull a patched base image, rebuild and redeploy, then check the version again.
- Find Brotli decoding in your codeSearch for express.json, bodyParser, createBrotliDecompress and fetch calls to servers you do not control.
- Check the Express lineRun npm ls express body-parser. Express 5 uses body-parser 2.x, which decodes Brotli bodies.
- Mark unsupported linesNode.js 20 and older get no fix. Plan an upgrade to 22.x or 24.x.
node --version
npm ls express body-parser
grep -rnE "express\.json|bodyParser|createBrotliDecompress|brotli" src/
Distribution packages keep their own version numbers. Read the vendor notice before you decide that a package is safe or not. Teams that lose track of their Node.js services can use External Attack Surface Management to list what faces the internet. That list is a good starting point for the update order.
What Can You Do If You Cannot Update Yet?
Upgrading is the fix. Vercel says to upgrade “regardless of WAF protections”. If you must wait, these steps lower the risk for one route each.
- Turn off body decoding in Express. body-parser’s documentation says that with
inflateset to false, compressed bodies are rejected. In its code, any request with a content encoding other than identity gets a 415 error. Setexpress.json({ inflate: false })and test your clients, because this also rejects gzip bodies. - Refuse Brotli request bodies at the edge. A proxy rule that rejects requests with
Content-Encoding: brremoves the request route. This is our own suggestion, not vendor advice. No vendor we opened publishes such a rule, so test it first. It does not touch responses your code fetches. - Use a WAF as an extra layer. Vercel says its WAF rules are live for every project, at no cost and with no setup, and that they block known exploit patterns. The rules cover traffic through Vercel’s network, not responses your functions fetch from other servers. Vercel also says to restrict direct access to external backends so traffic reaches them only through Vercel.
- Do not trust a missing vendor rule. We checked the public change logs of Cloudflare’s WAF and the AWS WAF managed rule groups on 22 October at about 19:54 UTC. We found no mention of Brotli or this CVE. That is not proof that no protection exists, only that we found no statement.
- Cut what an attacker would gain. Code runs with the permissions of the Node.js process. Run it as an unprivileged user and keep secrets out of its environment where you can.
- Move off Node.js 20. Vercel says its projects on Node.js 20 must switch to 22.x or 24.x and redeploy. Container images you build yourself need a rebuild on a patched base.
Does the Flaw Reach Beyond Node.js?
The CVE record places the root bug in Google’s Brotli library, versions 1.0.3 through 1.2.0. It tells users to update any Brotli libraries or binaries in that range to 1.0.10, 1.1.1 or 1.2.1. The Brotli project published all three releases on GitHub on 21 October at about 19:27 UTC. Each lists CVE-2026-111497 as a security fix.
- Python: the Brotli package on PyPI, whose home page is the Google repository, published version 1.2.1 on 22 October at 13:57 UTC.
- Debian: its security tracker, read on 22 October, lists Debian’s brotli packages 1.0.9-2 (bookworm), 1.1.0-2 (trixie) and 1.2.0-4 (unstable) as vulnerable, with no fixed version yet. It notes that Debian’s nodejs uses the system Brotli library and rates the nodejs entry “unimportant”. It lists Debian’s nodejs packages in bookworm (18.20.4), trixie (20.19.2), forky and sid (24.x) as vulnerable.
- Ubuntu and Red Hat: we found no page for the CVE on either site when we looked.
We have not tested other products that bundle Brotli, and we name none as affected. Ask software vendors whether their products include a Brotli build in the affected range.
What Else Did the Node.js Release Fix?
The same release fixes ten issues, and updates c-ares, OpenSSL, SQLite, Undici and the certificate list for the eMudhra intermediate CA compromise. Besides CVE-2026-111497, Node.js rates three more as high:
- CVE-2026-105482:
dns.resolvecuts off names that contain a NUL character. It affects 26.x, 24.x and 22.x. - CVE-2026-105483: a TLS certificate hostname bypass when an IP address is written with fullwidth digits. It affects 26.x and 24.x.
- CVE-2026-106069: a TLS certificate hostname bypass when the host loosely resolves to an IP address. It affects 26.x, 24.x and 22.x.
The other six are medium or low. Upgrading to the fixed versions covers all ten. For the certificate side, read our eMudhra guide for Python, uv and container teams.
How Is Node2Shell Different From PHP2Shell?
PHP2Shell is two flaws in the PHP engine. Node2Shell is one flaw in a Brotli decoder that Node.js bundles. The PHP flaws can be reached by requests to a web server running PHP. The Node.js flaw needs an app or library that decodes attacker-controlled Brotli data, which is common but not universal. The Node.js release came first, at 10:38 UTC on 21 October, and PHP followed later that day. Our PHP2Shell analysis covers the PHP side, and the PHP2Shell timeline of the first 36 hours shows how the public reaction ran.
The name followed the same pattern. In our X capture, the first post using “Node2Shell” is from 21 October at 17:08 UTC. Ron Masas used it in his post a day later. Neither the Node.js advisory nor the CVE record uses it.
What Is the Security Community Saying?
We collected public posts on X from 21 October (11:55 UTC) to 22 October (19:48 UTC) that matched four searches. The searches were “node2shell”, “CVE-2026-111497”, “brotli rce” and “brotli node.js vulnerability”. We read counts and themes only. The capture holds 444 unique posts.
- Volume and timing. The busiest hours were 15:00 UTC on 21 October (26 posts) and 02:00 UTC on 22 October (25 posts). Only 19 of the 444 posts use the word “Node2Shell”.
- Languages. 284 posts are in English (64%), 62 in Japanese (14%) and 27 in Chinese (6%).
- A bad week story. 205 posts (46%) also mention PHP, 113 (25%) mention eMudhra and 89 (20%) mention both. Most treat Node.js as one item in a list of the week’s incidents.
- Patch talk. 192 posts (43%) talk about patching or fixed versions, and 25 (6%) about mitigations.
- Vendor and researcher voices. Vercel’s developer account posted on 21 October at 23:24 UTC that its WAF rules are live. Ron Masas posted on 22 October at 17:06 UTC. Links to nodejs.org appear in 87 posts.
Our keyword filter marked 46 posts as exploit claims, 11 as proof of concept, 11 as scanning, 14 as possible sales and 15 as possible scam tokens. The filter is crude. In a sample of the sale and scam-token flags, most were roundup posts about the week’s incidents, not exploit offers. We opened none of the links in these posts and we link none here.
Read the numbers as a view of one platform, not of all researchers. The practical warning stands: during a loud week, fake exploit tools, “checkers” and tokens appear. Take fixes and advice only from Node.js, your vendors and your national CERT.
What Happened When?
- 21 Oct 2026, 10:38 UTCNode.js ships the fixesGitHub shows v22.23.4, v24.22.1 and v26.12.1 published at this time. The advisory page is dated 21 October.
- 21 Oct 2026, 17:08 UTCThe name appearsThe first post using “Node2Shell” in our X capture.
- 21 Oct 2026, about 19:27 UTCBrotli project releasesBrotli 1.0.10, 1.1.1 and 1.2.1 appear on GitHub, each listing CVE-2026-111497 as a security fix.
- 21 Oct 2026, 23:24 UTCVercel announces WAF rulesVercel’s developer account says its WAF rules are live. Vercel’s bulletin is dated 21 October.
- 22 Oct 2026, 13:35 UTCCVE record publishedGoogle’s CVE record lists a 9.2 score on CVSS 4.0 and the affected Brotli range.
- 22 Oct 2026, 13:57 UTCPyPI Brotli 1.2.1The Python Brotli package gets version 1.2.1.
- 22 Oct 2026, 14:15 UTCCISA adds data to the recordCISA lists exploitation “none”, automatable “no” and technical impact “total”.
- 22 Oct 2026, 14:17 UTCNVD record appearsNVD lists the CVE as awaiting analysis.
- 22 Oct 2026, 17:06 UTCResearcher statementRon Masas says his team reproduced the flaw as pre-authentication RCE.
For the weakness in plain terms, see our glossary entry on remote code execution, and the CVE-2026-111497 vulnerability page for the short fact sheet. Teams that need to rank this against the rest of the week can use vulnerability intelligence to decide what to patch first.
