Izkuna
Luis Martinez

Node2Shell: when the Brotli decoder becomes a remote code execution path

CVE-2026-111497 is an out-of-bounds write in the Brotli decoder bundled with Node.js and .NET. Patched builds exist; the hard part is finding every runtime.

Brotli Node.js .NET Vulnerability Management
Node2Shell: when the Brotli decoder becomes a remote code execution path

A compression library is not usually on a board's risk register. CVE-2026-111497 is a reminder that it should be.

The flaw is an out-of-bounds write in the Brotli decoder, triggered by malformed compressed input. It can corrupt memory and, in the worst case, allow remote code execution. The Singapore Cyber Security Agency rates it 9.8 out of 10 and describes an unauthenticated attacker sending a crafted Brotli stream to corrupt decoder memory or disclose sensitive information. Researchers nicknamed it "Node2Shell"; some write-ups also call it HTTP2Shell.

Who shipped fixes

  • Node.js released patched versions on October 21, 2026: 22.23.4, 24.22.1 and 26.12.1. End-of-life lines 25.x, 23.x, 20.x and older will not receive a fix.
  • Bun fixed the issue in 1.4.4.
  • Microsoft shipped out-of-band .NET updates on October 25, 2026. The Singapore advisory lists .NET 8, 9, 10 and 11 as affected.
  • The underlying Brotli library versions affected range from 1.0.3 through 1.2.0. NVD points to 1.0.10, 1.1.1 or 1.2.1 depending on the branch.

The dangerous assumption is that "we use Node.js" is enough to scope this. The decoder is also bundled in runtimes, container base images, serverless layers and third-party binaries.

How an attacker reaches the decoder

Exploitation requires the application to decompress attacker-controlled Brotli data. Three common paths:

  1. Compressed request bodies. Express 5 and body-parser 2.x decode Content-Encoding: br. A bare Node HTTP server does not, but many frameworks and proxies do.
  2. Outbound requests. Node's fetch() decompresses Brotli responses automatically. If your server fetches a URL an attacker can influence, the response passes through the decoder.
  3. Direct use of node:zlib. Any code calling the Brotli functions on untrusted input is in scope.

Distro-packaged Node.js may link the system Brotli library instead of the bundled one. That changes which component you need to update, so verify rather than assume.

Exploitation status, stated carefully

Node.js had no confirmed in-the-wild exploitation when it published the patches. By October 30, however, Singapore's CSA reported a public proof of concept and said the flaw was "reportedly being actively exploited". That is enough to treat internet-facing services as urgent.

A verification checklist

  1. Find every runtime. Run node --version on hosts, container images, CI runners and serverless layers. Check .nvmrc, Dockerfiles and lockfiles for pinned versions.
  2. Upgrade to 22.23.4, 24.22.1, 26.12.1 or newer. Move off EOL lines rather than looking for a backport.
  3. Rebuild and redeploy images. Changing a tag without rebuilding can leave the old binary in the layer cache, and a pinned node:22.23.3-alpine stays vulnerable.
  4. Update .NET and Bun where they are part of the stack, and confirm the patched build is the one running.
  5. Check third-party services. A vendor API that decompresses compressed input on your behalf is part of your supply chain.
  6. Use edge controls only as a stopgap. Rejecting Content-Encoding: br at the proxy reduces exposure, but it does not cover Brotli responses your application fetches from elsewhere.

Why this class of bug keeps appearing

Brotli, zlib, image parsers, PDF generators, XML parsers: the components that process untrusted input are often written in memory-unsafe languages and updated less visibly than the application framework. They are also frequently bundled rather than installed, which hides them from dependency scanners.

For a small team, the workable control is inventory plus a rule: anything that parses attacker-controlled data gets patched on the same schedule as the public website, not on a separate, slower one.

Where an audit fits

Izkuna's Web Security Audit — Express reviews the application, its dependencies and server configuration in five days at the current launch price of $600. If a component needs a coordinated fix, Remediation Support helps your team close it, and Retest & Remediation Verification confirms the new runtime is actually serving traffic.

Compression should be invisible to users. It should not be invisible to your asset inventory.

Sources

If you are unsure which runtimes your services use, start with a free 30-minute diagnostic.