Rorix Technologies
Engineering6 min read

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.

Node.jsSecurityCVE-2026-111497Node2ShellNestJSExpressDevSecOps
Node2Shell (CVE-2026-111497): What It Is and How to Protect Your Node.js Apps
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 
CVECVE-2026-111497
SeverityCVSS v4.0 9.2 (Critical)
WhereGoogle's Brotli library inside Node.js
ImpactCrash, 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.

SetupAt risk?
Express 5 with express.json()Yes, by default
Server-side fetch() to untrusted URLsYes
Koa, or Fastify with @fastify/compressYes
Express 4 body-parserNot through body-parser
Bare Node.js HTTP serverNo

Fix internet-facing services that decode untrusted Brotli first.

 

Which versions are fixed?

Node.js lineFixed version
26.x26.12.1
24.x LTS24.22.1
22.x LTS22.23.4
25.x, 23.x, 21.x, 20.x and olderNo 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.

TechnologyWhat it isWhere Node2Shell matters
Node.jsJavaScript runtime for servers and toolsEverywhere it runs: the bug is in its built-in Brotli decoder
NestJSServer-side framework built on Node.jsAPI servers, because NestJS 11 uses Express 5 by default
AngularFront-end frameworkSSR server, dev server and build machines
ReactUI library, often used with Next.jsSSR servers, API routes and build machines
VueFront-end framework, often used with NuxtSSR 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.

  1. Upgrade the runtime to a fixed version.
  2. Rebuild Docker images. Run docker pull first, since a cached node:24 tag stays old. Pin to 24.22.1 or later.
  3. Check inside the container with node --version.
  4. Restart every service. Running processes keep the old runtime until restarted.
  5. 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.

  1. Upgrade Node.js on the SSR server, if you use server-side rendering.
  2. Check the SSR server's body parser. If it uses Express 5 with express.json(), set inflate: false until patched.
  3. Avoid server-side fetch() to untrusted URLs. Node.js decodes Brotli responses even if you ask for no compression.
  4. 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.

  1. Upgrade Node.js on SSR servers, API route hosts, containers and CI runners.
  2. Audit API routes. If a route uses Express 5, Koa, or Fastify with @fastify/compress, apply the matching fix.
  3. Audit server-side fetch(). Link previews, webhooks and proxies that fetch user-supplied URLs are typical targets.
  4. 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.

  1. Upgrade Node.js on SSR servers, server API hosts, containers and CI runners.
  2. Audit server API handlers for any middleware that decompresses Brotli bodies.
  3. Audit server-side fetch() to URLs you don't control.
  4. 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

Work with Rorix

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.

Node2Shell (CVE-2026-111497): What It Is and How to Protect Your Node.js Apps