Hacktron

Patched. Google, the CVE’s assigner, rates it critical (CVSS v4.0 9.2), while Node.js rates it high.

Overview

Node2Shell is CVE-2026-111497, an out-of-bounds write in Google’s Brotli decoder. Crafted Brotli-compressed data can crash a process, disclose process memory, or (in some setups) run code. It affects Node.js, Python’s Brotli packages, Bun, Envoy, .NET, and other software that bundles the decoder. Fixes shipped from October 21, 2026. Update, rebuild, and restart.

Other names for the bug

Imperva named the Node.js exposure Node2Shell, and that is where the bug first drew broad attention. HTTP2Shell is a later name for the wider impact. Despite the name, this is not an HTTP/2 bug, or necessarily an HTTP bug. Any attacker-controlled Brotli stream that reaches an affected decoder can trigger it. Broccoli2Shell is the name used by an independent tracking site that lists affected software.

All three are CVE-2026-111497. Patching for one patches for all of them.

Affected software

  • Google Brotli: 1.0.x from 1.0.3 before 1.0.10, plus 1.1.0 and 1.2.0, on all platforms.

  • Node.js: 22.x, 24.x, and 26.x before the fixed releases. Node.js says end-of-life versions are always affected when a security release ships; that includes 20.x, 23.x, and 25.x.

  • Python: the Brotli package from 1.0.3 up to 1.2.1, and brotlicffi from 1.0.3 up to 1.2.1.0. Clients such as urllib3, Requests, HTTPX, and aiohttp decode Brotli responses automatically when one of these packages is installed, even if your code never imports it.

  • Bun: 1.0.21 up to 1.4.4.

  • Envoy: deployments with the Brotli decompressor configured.

  • .NET: .NET 8, 9, and 10 runtimes before the fixed releases, and .NET 11 previews. It is only reachable through ASP.NET Core request decompression with the br provider, HttpClient automatic Brotli decompression, or direct use of BrotliStream or BrotliDecoder, none of which is on by default. .NET Framework is not affected.

  • Other software: anything that bundles or links an affected Brotli, such as curl builds that decode Brotli responses (--compressed) using an affected libbrotli. Check each vendor’s advisory and your OS packages.

When the bug is reachable

An attacker must get a crafted Brotli stream decoded by a vulnerable copy. Common routes:

  • Services that decompress incoming bodies sent with Content-Encoding: br. Imperva confirmed this path through Express 5.0.0–5.3.0 and body-parser 2.0.0–2.3.0 with the raw() and json() parsers. Running Express alone does not mean you are exposed, and a bare Node.js HTTP server does not decode incoming Brotli bodies.

  • Clients that decode Brotli responses from servers they don’t control, for example webhooks or URL previews. Imperva confirmed this path through Node.js’s built-in fetch().

  • Code that passes untrusted data, including uploaded or imported files, to node:zlib’s Brotli functions or equivalent APIs in other languages.

What to do

  1. Find every copy of Brotli in Node.js runtimes (including inside container images), Python environments, .NET apps, and other runtimes, proxies, and tools that bundle it.

  2. Update Node.js to 22.23.4, 24.22.1, or 26.12.1 (or later). Move off end-of-life Node.js lines.

  3. Update Python’s Brotli to 1.2.1 and brotlicffi to 1.2.1.0, then regenerate lockfiles.

  4. Update the system Brotli library to 1.2.1, or to 1.1.1 or 1.0.10 on those branches. Distribution packages may backport the fix without changing the version number, so follow your distribution’s advisory.

  5. Update everything else that bundles Brotli, including Bun, Envoy, and .NET.

  6. Rebuild, redeploy, and restart. Running processes keep the old decoder until they restart. Rebuild Bun bun build --compile executables, republish .NET NativeAOT apps, and rebuild container images.

  7. If you can’t update straight away, note that Node.js says there is no workaround. As a stopgap, Aikido suggests rejecting requests with Content-Encoding: br at your proxy or middleware. This does not protect responses your services fetch, so prioritize updating services that call untrusted servers. For .NET, Microsoft suggests removing the br provider from request decompression and Brotli from HttpClient automatic decompression.

Fixed versions

Component Fixed in
Google Brotli 1.2.1, 1.1.1, 1.0.10
Node.js 26.12.1, 24.22.1, 22.23.4
Python Brotli 1.2.1
brotlicffi 1.2.1.0
Bun 1.4.4
Envoy 1.40.0, 1.39.3, 1.38.6
Envoy (older) 1.37.8, 1.36.12
.NET 10.0.14, 9.0.22, 8.0.33
.NET 11 11.0.0-rc.3

Timeline

  1. Fix lands in Brotli's source, not marked as a security fix

  2. Brotli 1.0.10, 1.1.1 and 1.2.1 released

  3. Node.js 22.23.4, 24.22.1 and 26.12.1 released

  4. Imperva reports code execution on Node.js 24.22.0

  5. GitHub advisory for Python Brotli and brotlicffi; fixes on PyPI

  6. Bun and Envoy publish advisories

  7. Microsoft publishes the .NET advisory

The fix (commit 0ed4268, “Detect and report invalid stream earlier”) was public in Brotli’s source from February 27, but nothing marked it as a security fix and no release shipped it until October. Software built from release tarballs or older vendored copies stayed affected until then.

Technical summary

A Brotli stream can tell the decoder to switch between block types. A crafted stream asks for a switch after declaring only one block type. In the vulnerable code, DecodeBlockTypeAndLength() returned the same result for this format error as for “not enough input yet,” so the streaming decoder waited for more data (CWE-252, unchecked return value).

As more input arrived, the decoder kept appending it to an eight-byte internal buffer and wrote past its end into neighboring decoder state (CWE-787, out-of-bounds write).

Depending on what is overwritten, the result is a crash, disclosure of process memory, or code execution in the process. Imperva reached code execution on the official Node.js 24.22.0 Linux arm64 image, which took multiple attempts. Imperva has not released an exploit, and public crash demonstrations are not the same as a reliable RCE exploit.

In the fixed decoder, an impossible block switch returns a specific error, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH, and decoding stops instead of buffering. Patched Node.js rejects Imperva’s inputs and keeps running.

The CVSS v4.0 score is 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N). “Attack requirements: present” reflects that the target must decode Brotli from an attacker-influenced source. Microsoft scores the .NET exposure CVSS v3.1 8.1.

References