Patched. Google, the CVE’s assigner, rates it critical (CVSS v4.0 9.2), while Node.js rates it high.
Overview
Node2Shell is CVE-
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-
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
brprovider,HttpClientautomatic Brotli decompression, or direct use ofBrotliStreamorBrotliDecoder, 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 theraw()andjson()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
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.
Update Node.js to 22.23.4, 24.22.1, or 26.12.1 (or later). Move off end-of-life Node.js lines.
Update Python’s Brotli to 1.2.1 and brotlicffi to 1.2.1.0, then regenerate lockfiles.
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.
Update everything else that bundles Brotli, including Bun, Envoy, and .NET.
Rebuild, redeploy, and restart. Running processes keep the old decoder until they restart. Rebuild Bun
bun build --compileexecutables, republish .NET NativeAOT apps, and rebuild container images.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: brat 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 thebrprovider from request decompression and Brotli fromHttpClientautomatic 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
-
Fix lands in Brotli's source, not marked as a security fix
-
Brotli 1.0.10, 1.1.1 and 1.2.1 released
-
Node.js 22.23.4, 24.22.1 and 26.12.1 released
-
Imperva reports code execution on Node.js 24.22.0
-
GitHub advisory for Python Brotli and brotlicffi; fixes on PyPI
-
Bun and Envoy publish advisories
-
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
GitHub advisory GHSA-9v8h-qqgm-4m35 (Python Brotli, brotlicffi)
Imperva: Node2Shell, from Brotli data to remote code execution
Aikido: Python packages affected by Node2Shell (Python clients, curl, proxy stopgap)
Broccoli2Shell (independent list of affected software)
Credits, from the Node.js advisory: reported by Khai Tran and Sylvie Mayer of OpenAI Codex Security; fixed by mcollina and aduh95