What happened
On 21 October 2026 the Node.js project released 22.23.4, 24.22.1 and 26.12.1 to fix CVE-2026-111497, an out-of-bounds write in the Brotli decoder that Node.js bundles. The Node.js advisory rates it high. Google, as the CVE Numbering Authority, scores it 9.2 under CVSS v4.0. Google published fixed Brotli releases (1.0.10, 1.1.1 and 1.2.1) the same day, although Help Net Security notes that the upstream code fix had been public in the Brotli repository since 27 February without a release or advisory.
The flaw has several names in circulation: Node2Shell, Brotli2Shell, HTTP2Shell and Broccoli2Shell. They all refer to this one CVE.
Is it being exploited?
- 26 October: threat intelligence firm ELLIO reported that its sensors recorded an exploitation attempt at 15:08 UTC against the official Node.js 24.22.0 x86-64 build. ELLIO says the source had previously been seen exploiting PHP2Shell, probing Palo Alto GlobalProtect and FortiOS SSL VPN, and scanning Kubernetes interfaces, which it takes as a sign of an operator focused on mass exploitation.
- ELLIO also says that this attacker’s own exploit chain did not work in its lab: it produced no shell in 50 attempts against a vulnerable test target, and it describes the attempt as likely first-generation. ELLIO’s own chain, built from public components, did get a shell. Better versions of the attacker’s chain are likely to follow.
- 27 October: CISA added CVE-2026-111497 to the KEV catalogue (catalogue version 2026.10.27), with a due date of 10 November 2026 for US federal civilian agencies. The entry records ransomware campaign use as unknown.
- Public proof-of-concept code exists. Imperva reported code execution against the official Node.js 24.22.0 Linux arm64 image after multiple attempts, and ELLIO reported the same against the official 24.22.0 x86-64 build. Both were lab results.
Tenable’s 26 October FAQ said it had not independently confirmed ELLIO’s observation, so treat that detail as ELLIO’s report. The KEV listing is CISA’s own evidence of exploitation. None of the sources we reviewed names an organisation as compromised. Treat the flaw as actively targeted regardless.
Who is affected
Any application that decompresses attacker-controlled Brotli data with a vulnerable decoder is potentially at risk. Having the library installed is not the same as being exposed: what matters is whether untrusted Brotli data can reach the decoder.
The main exposure paths are:
- Servers that decompress incoming request bodies sent with
Content-Encoding: br. Akamai notes that Express 5 and body-parser 2 do this by default for their JSON, raw, text and urlencoded parsers. A bare Node.js HTTP server does not decode request bodies on its own. - Clients that decompress responses automatically, such as Node.js
fetch()and Bun’sfetch. A malicious or compromised server can then target the client. In Python, if the Brotli or brotlicffi package is installed, urllib3, requests, httpx and aiohttp will decode Brotli responses. - Direct use of Brotli APIs, such as
node:zliband the .NETSystem.IO.CompressionBrotli classes. - Brotli data inside files. JFrog Security Research, as summarised by Tenable, reached FFmpeg through JPEG XL metadata (instruction-pointer control, but no demonstrated code execution), caused a denial of service in Apache Arrow and crashed a tested ClickHouse server.
Fixed versions
These are the fixed versions from each project’s own advisory or release notes, except the Python packages, which are taken from Tenable’s summary.
| Project | Fixed in | Notes |
|---|---|---|
| Google Brotli | 1.0.10, 1.1.1, 1.2.1 | Affects 1.0.3 to 1.2.0 except the fixed releases |
| Node.js | 22.23.4, 24.22.1, 26.12.1 | 20.x, 23.x and 25.x are end of life and will not be fixed |
| Bun | 1.4.4 | Rebuild any executable made with bun build --compile |
| Envoy Proxy | 1.36.12, 1.37.8, 1.38.6, 1.39.3, 1.40.0 | Exposed only where the Brotli decompressor is configured |
| Istio | 1.29.9, 1.30.6, 1.31.2 | Exposed only where Brotli decompression is enabled, for example through an EnvoyFilter. 1.29 reached end of life on 15 October |
| Microsoft .NET | 8.0.33, 9.0.22, 10.0.14, 11 RC3 | .NET Framework is not affected. NativeAOT and self-contained applications must be rebuilt |
| Python Brotli / brotlicffi | 1.2.1 / 1.2.1.0 | Per Tenable’s summary |
| PHP for Windows | 8.2.35-1, 8.3.36-1, 8.4.27-1, 8.5.12-1 | Rebuilds with the same PHP version number, so check the -1 suffix |
Microsoft says .NET applications are not exposed merely because an affected package is installed: ASP.NET Core request decompression and HttpClient automatic response decompression are off by default. PHP says that on Windows the decoder is reached through the cURL extension when automatic HTTP response decompression is enabled, which cURL leaves off by default.
Tenable reported that, as of 26 October, ClickHouse had merged a fix without shipping a release and the Apache Arrow issue was still open. Check their current status. Akamai says its telemetry shows 61% of networks running affected Node.js versions.
What to do now
- Inventory. Find every Node.js, Bun, .NET, Envoy or Istio and Python service, including containers and serverless functions. Check the Node.js release version, not
process.versions.brotli: ELLIO notes that it reads 1.2.0 on both patched and unpatched builds. - Patch and redeploy. Install the fixed runtime or library, rebuild container images, redeploy and restart. A patched package on disk does nothing for a process still running the old decoder. Updating the operating system’s Brotli library does not fix software that bundles its own copy, such as Node.js and Bun.
- Move off end-of-life Node.js. 20.x, 23.x and 25.x will not receive a fix. The Node.js advisory offers no workaround, so Akamai describes upgrading as the only complete remediation.
- Reduce exposure while you patch. Where it fits your service, block or log inbound requests with
Content-Encoding: brat the proxy or load balancer. Turn off Brotli decoding in HTTP clients that talk to untrusted servers. RemovingbrfromAccept-Encodingalone is not enough, because a hostile server can still send Brotli. Disabling Brotli compression on your own origin or CDN does not help either. Vendor-documented options include setting the body-parserinflateoption to false (compressed bodies are then rejected with HTTP 415), passingdecompress: falseto Bun’sfetch, removing thebrprovider from an existing .NET decompression setup, and removing the Brotli and brotlicffi packages from Python environments until they are updated. Disabling the Brotli filter in Envoy or Istio forwards compressed bytes unchanged, so downstream services that decode Brotli stay exposed. - Restrict and segment. Limit inbound access to Node.js services to the sources that need it, and restrict their outbound connections.
What to look for
- Inbound requests with
Content-Encoding: brand unusually large bodies for your service. The attempt ELLIO recorded was a single request body of about 23 MB. ELLIO also recorded a scanner that identifies itself asnode2shell-checkand sends Brotli-encoded bodies to find hosts that decode Brotli. - Bursts of Node.js crashes, worker restarts or crash loops shortly after such requests. ELLIO says a missed attempt usually crashes the worker. Some other decoders, including Python’s, hang instead of crashing.
- Core dumps created after those crashes. ELLIO notes that they can contain other users’ session cookies and tokens. Restrict access to them and expire them. Containers often have no core pattern configured, in which case the main effect is on availability.
- ELLIO published the source address and payload hash for the 26 October attempt in its write-up. Check them against your edge logs.
- Unexpected child processes, outbound connections or new files from Node.js service accounts during any period when an unpatched build was reachable. This is general hygiene, not a published indicator for this flaw.
How PoCForge can help
If you need a view of where Brotli decompression is reachable from the internet in your estate, or want your patching independently verified, get in touch and we can scope an assessment with you.
Sources
- Node.js, “Wednesday, October 21, 2026 Security Releases”
- Google Brotli v1.2.1 release (21 Oct 2026)
- CISA, “CISA Adds Two Known Exploited Vulnerabilities to Catalog” (27 Oct 2026)
- CISA Known Exploited Vulnerabilities catalogue (version 2026.10.27)
- ELLIO, “Node2Shell: remote code execution on stock Node.js builds (CVE-2026-111497)” (25 Oct 2026, updated 26 Oct)
- Tenable, “Brotli2Shell: Frequently asked questions” (26 Oct 2026)
- Akamai, “Inside Node2Shell: A Closer Look at CVE-2026-111497” (26 Oct 2026)
- Microsoft, .NET security advisory for CVE-2026-111497 (25 Oct 2026)
- Envoy advisory GHSA-3wvj-j6qm-62mr (23 Oct 2026)
- Istio, ISTIO-SECURITY-2026-007 (15 Oct 2026)
- Bun advisory GHSA-663w-cv8g-jj2p (23 Oct 2026)
- PHP, “Updated PHP Windows builds for Brotli security fix” (26 Oct 2026)
- Help Net Security, “Brotli bug reaches far beyond Node.js (CVE-2026-111497)” (27 Oct 2026)
PoCForge publishes offensive-security research to explain attack paths and defensive controls. This article summarises public advisories and reporting only; it is not an exploit guide and does not describe a named client engagement.
