Node2Shell (CVE-2026-111497): Brotli decoder flaw now in CISA KEV – what to patch and how to cut exposure

CVE-2026-111497 in Google's Brotli decoder is in CISA KEV and ELLIO has reported exploit traffic. Update Node.js, Bun, .NET, Envoy, Istio and Python Brotli, restart, and cut exposure while you patch.

Why this matters now. CVE-2026-111497 is an out-of-bounds write in Google’s Brotli decoder. Crafted compressed data can crash a process, leak memory or, in some builds, lead to code execution. Node.js shipped fixes on 21 October 2026, ELLIO reported exploit traffic on 26 October, and CISA added the flaw to the Known Exploited Vulnerabilities (KEV) catalogue on 27 October with a due date of 10 November. Patch every runtime that bundles its own Brotli copy, restart what is running, and reduce exposure while you do.

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’s fetch. 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:zlib and the .NET System.IO.Compression Brotli 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

  1. 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.
  2. 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.
  3. 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.
  4. Reduce exposure while you patch. Where it fits your service, block or log inbound requests with Content-Encoding: br at the proxy or load balancer. Turn off Brotli decoding in HTTP clients that talk to untrusted servers. Removing br from Accept-Encoding alone 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-parser inflate option to false (compressed bodies are then rejected with HTTP 415), passing decompress: false to Bun’s fetch, removing the br provider 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.
  5. 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: br and 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 as node2shell-check and 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

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.