Node2Shell (CVE-2026-111497): What It Is and How to Protect Your Node.js Apps
A critical Brotli bug in Node.js can crash servers or run attacker code. Learn who is at risk and how to fix it in Node.js, NestJS, Angular, React and Vue.

On this page29 sections
TL;DR: Update Node.js to 22.23.4, 24.22.1 or 26.12.1. If you run Node.js 20, 21, 23 or 25, move to a supported line, because those will never get a fix.
What is Node2Shell?
On October 21, 2026, Node.js shipped fixes for a memory bug in the Brotli decoder it bundles. About a day later, public proof-of-concept code appeared, and Imperva showed it could run attacker code on an official Node.js Docker image. The bug is now known as Node2Shell.
| Quick facts | |
|---|---|
| CVE | CVE-2026-111497 |
| Severity | CVSS v4.0 9.2 (Critical) |
| Where | Google's Brotli library inside Node.js |
| Impact | Crash, memory leak, or remote code execution |
| Exploited in the wild? | Not confirmed as of October 23, 2026 |
Brotli is a compression format, like gzip. The bug is not in your npm packages. It is inside the Node.js runtime itself, so npm update will not fix it.
How the attack works
An attacker sends a specially broken Brotli stream. The old decoder should stop with an error, but instead it treats the broken input as "incomplete" and keeps going. It then writes past the end of its memory buffer. Most of the time the server crashes. In one tested setup, it ran the attacker's code.
The data can reach your app in two ways: as a compressed request body (Content-Encoding: br), or as a compressed response when your server calls fetch() on a URL an attacker controls.
Are you at risk?
You are at risk only if your app decompresses Brotli data that someone else controls.
| Setup | At risk? |
|---|---|
Express 5 with express.json() | Yes, by default |
Server-side fetch() to untrusted URLs | Yes |
Koa, or Fastify with @fastify/compress | Yes |
| Express 4 body-parser | Not through body-parser |
| Bare Node.js HTTP server | No |
Fix internet-facing services that decode untrusted Brotli first.
Which versions are fixed?
| Node.js line | Fixed version |
|---|---|
| 26.x | 26.12.1 |
| 24.x LTS | 24.22.1 |
| 22.x LTS | 22.23.4 |
| 25.x, 23.x, 21.x, 20.x and older | No fix: upgrade to a supported line |
Bun users should move to 1.4.4 or newer. On some Linux distros, Node.js uses the system Brotli library, so update that package too.
How to prevent it
The real fix is the same everywhere: run a fixed Node.js version. What changes per technology is where Node.js runs and how Brotli data can reach it.
| Technology | What it is | Where Node2Shell matters |
|---|---|---|
| Node.js | JavaScript runtime for servers and tools | Everywhere it runs: the bug is in its built-in Brotli decoder |
| NestJS | Server-side framework built on Node.js | API servers, because NestJS 11 uses Express 5 by default |
| Angular | Front-end framework | SSR server, dev server and build machines |
| React | UI library, often used with Next.js | SSR servers, API routes and build machines |
| Vue | Front-end framework, often used with Nuxt | SSR servers, server API routes and build machines |
Node.js (every project)
About: Node.js is the JavaScript runtime that every framework below runs on. Because Node2Shell lives inside the runtime, upgrading Node.js protects every app on that machine at once.
- Upgrade the runtime to a fixed version.
- Rebuild Docker images. Run
docker pullfirst, since a cachednode:24tag stays old. Pin to24.22.1or later. - Check inside the container with
node --version. - Restart every service. Running processes keep the old runtime until restarted.
- Run as a non-root user and keep secrets out of the environment.
NestJS
About: NestJS is a framework for building APIs and backend services on Node.js. It sits on top of an HTTP layer, Express by default or Fastify, so its exposure comes from how that layer parses request bodies.
NestJS 11 uses Express 5 by default, which decodes Brotli bodies. Upgrade Node.js, and until then turn off body decompression:
const app = await NestFactory.create<NestExpressApplication>(AppModule, { bodyParser: false });
app.use(express.json({ inflate: false }));This also blocks gzip bodies, so test your clients first. On the Fastify adapter, check for @fastify/compress.
Angular
About: Angular is a front-end framework whose app code runs in the browser. Browser code is not affected, because the bug lives in the Node.js runtime. Node.js is still used for server-side rendering (SSR), the dev server and builds.
- Upgrade Node.js on the SSR server, if you use server-side rendering.
- Check the SSR server's body parser. If it uses Express 5 with
express.json(), setinflate: falseuntil patched. - Avoid server-side
fetch()to untrusted URLs. Node.js decodes Brotli responses even if you ask for no compression. - Upgrade Node.js on build machines and CI runners.
React
About: React is a UI library that runs in the browser. Browser bundles are not affected. Risk comes from server code on Node.js, such as Next.js SSR and API routes.
- Upgrade Node.js on SSR servers, API route hosts, containers and CI runners.
- Audit API routes. If a route uses Express 5, Koa, or Fastify with
@fastify/compress, apply the matching fix. - Audit server-side
fetch(). Link previews, webhooks and proxies that fetch user-supplied URLs are typical targets. - Check your hosting platform's Node.js runtime version.
Vue
About: Vue is a front-end framework that runs in the browser. Browser code is not affected. Risk comes from server code on Node.js, such as Nuxt SSR and server API routes.
- Upgrade Node.js on SSR servers, server API hosts, containers and CI runners.
- Audit server API handlers for any middleware that decompresses Brotli bodies.
- Audit server-side
fetch()to URLs you don't control. - Block Brotli request bodies at the proxy if your clients don't send them.
Extra layers while you patch
Block Content-Encoding: br request bodies at your proxy if clients don't need them, add WAF rules, and alert on unexpected shell spawns. These help, but only the runtime upgrade fixes the bug.
How to spot an attack
Failed attacks usually crash the Node.js process, and attackers often need several tries. Watch for a Node.js crash followed by a new program running in the same container, plus unexpected shells or outbound connections. A crash alone does not prove an attack, so compare it with your logs.
Automate the fix
Cognition (maker of Devin) released an open-source Vulnerability Fixes plugin. It finds Node.js versions across Dockerfiles, CI files, Helm, Terraform and Lambda configs, asks for approval, tests before and after, and opens one pull request per repo. You can install it with npx skills add CognitionAI/devin-vuln-fixes. Review the skill before you run it.
Conclusion
Node2Shell is not a bug in every Node.js app, only in apps that decode Brotli data they don't control. But the exploit code went public within a day of the fix. Find every Node.js runtime you run, upgrade it, rebuild and restart, and use the extra layers only as a stopgap.
Sources
Need engineers who stay?
Dedicated developers at $3,500 per developer per month, working your backlog on 2-week sprints with a named technical lead.