Skip to content
HackIT

Node2Shell (CVE-2026-111497): how to check Node.js and Brotli

A Brotli decoder flaw on CISA's exploited list can corrupt memory in Node.js and other software. Which versions are fixed, how to check yours, what to do.

HackIT Security Team

Security alert cover for CVE-2026-111497: CVSS 4.0 score 9.2, fixed in Node.js 26.12.1, Node.js 24.22.1, Node.js 22.23.4, Brotli 1.2.1, Brotli 1.1.1, and Brotli 1.0.10

In short: CVE-2026-111497, known as Node2Shell, is a flaw in Google's Brotli decoder: crafted compressed data can corrupt memory and possibly run code in Node.js and other software that decodes Brotli. CISA added it to its catalogue of known exploited vulnerabilities on 27 October 2026, and Google scores it 9.2 under CVSS 4.0. Update Node.js to 26.12.1, 24.22.1 or 22.23.4, update Brotli to 1.2.1, 1.1.1 or 1.0.10 or your distribution's fixed package, and rebuild container images.

What happened

On 21 October 2026, the Node.js project released fixes for a flaw in the Brotli decoder it bundles.

The CVE record, published on 22 October, places the bug in Google Brotli 1.0.3 to 1.2.0. With a crafted Brotli stream, an attacker who is not logged in can corrupt decoder memory, read memory contents, crash the process, or potentially run code. On 27 October, CISA added it to its Known Exploited Vulnerabilities catalogue. It also circulates as HTTP2Shell and Broccoli2Shell.

Google, which assigned the CVE, gives 9.2 under CVSS 4.0, and NVD gives 9.8 under CVSS 3.1. Red Hat gives 8.1 under CVSS 3.1 and rates it Important, because it scores attack complexity as high.

Imperva and ELLIO report running code on unpatched official Node.js builds in their own tests, and ELLIO says the public exploit gets a shell on vulnerable builds. Red Hat's CVE page, by contrast, says there is no public, reliable proof of concept for remote code execution.

Who is affected

Anything that decodes untrusted Brotli with an unfixed copy of the decoder. Red Hat's bulletin names HTTP servers and clients that accept Content-Encoding: br from untrusted peers.

In Node.js, the 26.x, 24.x and 22.x lines are affected, and Node.js says end-of-life versions always are. Exposure comes through node:zlib: zlib.brotliDecompress(), zlib.createBrotliDecompress(), and fetch() reading Brotli responses. According to Imperva, a bare Node.js HTTP server does not decode incoming Brotli bodies on its own, but Express 5 and body-parser 2.x can when their parsers are configured to. Aikido adds that because fetch() decodes responses automatically, a server an attacker controls can reach your application through its response; webhooks and features that call user-supplied addresses are typical targets.

Node.js is not the only one. NVD lists these as affected below the versions shown, in each release line:

SoftwareAffected below
Brotli library1.2.1, 1.1.1, 1.0.10
Node.js26.12.1, 24.22.1, 22.23.4
.NET8.0.33, 9.0.22, 10.0.14
Python brotlicffi1.2.1.0
Envoy1.39.3, 1.38.6, 1.37.8
Istio1.31.2, 1.30.6, 1.29.9
Bun1.4.4
Go port andybalholm/brotli1.2.7

GitHub's advisory gives 1.2.1 as the fixed version of the PyPI Brotli package. For .NET, Microsoft names three ways in: ASP.NET Core request decompression, HttpClient automatic response decompression and the System.IO.Compression Brotli APIs; the first two are off by default, and .NET Framework is not affected.

How to check whether you are affected

Check the Node.js version on every host and CI runner, and inside every container image; Aikido and Imperva note that a package inventory can miss a runtime bundled in an image:

node --version
docker run --rm <image> node --version

Do not rely on process.versions.brotli: ELLIO notes that the fixed releases kept the bundled version string, so it reads the same on patched and vulnerable builds.

To find where your application decodes Brotli, Aikido suggests listing Express and body-parser versions and searching code and dependencies for the decoder calls:

npm ls express body-parser
grep -rn -E "brotliDecompress|createBrotliDecompress" .

Some distributions build Node.js against the system Brotli library instead. Ubuntu marks its nodejs package not affected on 22.04 LTS and later for that reason; on 20.04 it uses its own copy and is vulnerable. The Debian tracker says Debian's nodejs uses the system library, although it still lists nodejs as vulnerable in bookworm and trixie. On RHEL 8 and 9, Node.js 24 from the nodejs:24 module bundles its own copy; Red Hat lists it, and nodejs:26 on RHEL 9, as affected with no fixed package as of 29 October. List the installed Brotli packages and compare them with your distribution's fixed version:

dpkg -l | grep -i brotli
rpm -qa | grep -i brotli
DistributionFixed brotli package
Debian 13 trixie1.1.0-2+deb13u1 (DSA-6582-1)
Debian 12 bookworm1.0.9-2+deb12u1 (DLA-4855-1)
Ubuntu 26.10, 26.04 LTS1.2.0-4ubuntu0.1, 1.2.0-3ubuntu0.1
Ubuntu 24.04 LTS, 22.04 LTS1.1.0-2ubuntu0.1, 1.0.9-2ubuntu0.1
RHEL 10brotli-1.1.0-8.el10_2.1 (RHSA-2026:90449)
RHEL 9brotli-1.0.9-10.el9_8.1 (RHSA-2026:90495)
RHEL 8brotli-1.0.6-5.el8_10 (RHSA-2026:90501)

Ubuntu also lists fixes for 16.04 to 20.04 through Ubuntu Pro.

What to do now

  1. Update Node.js to 26.12.1, 24.22.1 or 22.23.4, and move end-of-life lines to one of those. Update the system Brotli package, Python packages and other runtimes to fixed versions. Red Hat says that even where its Node.js uses the system library, that library must still be updated.
  2. Rebuild and restart. Updating the host does not fix copies bundled inside images or applications, as Microsoft notes for .NET. Red Hat says to rebuild containers when base images are updated, and Aikido notes that an image pinned to an old Node.js tag stays vulnerable until it is rebuilt on a fixed version. ELLIO advises restarting processes as well.
  3. If you cannot update today, Red Hat suggests configuring the reverse proxy or load balancer to strip or reject Content-Encoding: br from untrusted clients, and not decoding untrusted Brotli in Node.js until it is updated. The Node.js advisory gives no workaround.
  4. Look for signs. Imperva says unexpected process exits during decompression and decoder errors can show where to look first, but neither is a reliable sign of exploitation on its own. ELLIO has published indicators from an attempt it recorded on 26 October 2026, including the source address 94.154.43.7.

Do not count on blocking Brotli at the proxy alone: Aikido notes that it does not cover Brotli responses your application fetches.

What a penetration test would look for

This is a memory-safety bug in code that parses untrusted input. The question behind it is where your application accepts or fetches compressed data, and what decodes it: request bodies, webhooks, features that fetch user-supplied addresses, and the proxies in front. A web application penetration test maps those paths and checks what an attacker can send through them.

If you want to know where your application decodes data it cannot trust, talk to a tester.

Sources