Skip to main content
CVE-2026-111497 Critical Patch Available

CVE-2026-111497: Google Brotli Decoder Out-of-Bounds Write Enables RCE (Node2Shell)

CVE Details

CVE ID CVE-2026-111497
CVSS Score 9.2
Severity Critical
Vendor Google
Product Brotli
Patch Status Available
Published October 28, 2026
EPSS Score 55.5%
CISA Patch Deadline November 10, 2026

Background

Brotli is a compression format and library used in web servers, browsers, HTTP clients and language runtimes. Because it is embedded in many products, one decoder bug reaches far beyond Google’s own repository. CVE-2026-111497, nicknamed Node2Shell by Aikido and ELLIO, affects the Brotli decoder and, through it, Node.js, Bun and other software that bundles it. CISA added it to KEV on October 27, 2026, and its notes flag that the flaw “affects an open-source component, third-party library, protocol, or proprietary implementation that could be used by different products.”

Technical Mechanism

NVD’s description, from Google’s CNA, is a buffer overflow in c/dec/decode.c in Brotli 1.0.3 through 1.2.0 on all platforms. A remote, unauthenticated attacker can use a crafted stream to corrupt adjacent decoder state memory, disclose memory, cause denial of service or potentially execute code. The CNA lists CWE-252 (unchecked return value) and CWE-787 (out-of-bounds write).

The Node.js advisory gives the mechanism: “An invalid block switch was reported as a temporary need for more input instead of a permanent format error, so the streaming decoder kept appending input bytes to an eight-byte internal buffer.” In Node.js, an attacker who can supply Brotli data that an application decompresses with node:zlib can corrupt process memory, which can lead to a crash, memory disclosure or code execution.

Reachability depends on the application. Aikido lists three paths: Express 5 and body-parser 2.x decoding Content-Encoding: br request bodies, fetch() on Brotli responses, and direct node:zlib use on untrusted input. It says a bare Node.js HTTP server does not decode incoming Brotli bodies on its own.

Real-World Exploitation Evidence

CISA added the CVE to KEV on October 27, 2026, due November 10, ransomware use “Unknown.”

ELLIO’s October 25 post, updated October 26, says exploit traffic is in the wild and advises treating the bug as exploited. This is a single vendor’s telemetry. Its reported observations:

  • A scanner-like checker (user agent Mozilla/5.0 (compatible; node2shell-check/1.0), AS44620 in Turkey), whose address ELLIO first observed on June 13, 2026. ELLIO’s October write-up describes 20 Content-Encoding: br POST bodies from the checker (undated in the text); none of the 20 carried the block-switch construct. The June date is the address’s first sighting, not the date of those POSTs, and the CVE only became public on October 22.
  • On October 26 at 15:08 UTC, a 23,069,983-byte Brotli body from 94.154.43[.]7, targeting Node.js 24.22.0 on x86-64 with what ELLIO calls an original ROP chain. SHA-256 7fcbdaaecd4419e2930927844f3b772668204737a4e7602a2290c991c93c5c4b.
  • In ELLIO’s lab, that chain produced zero shells in 50 attempts, and ELLIO believes it likely never reached its final stage.

ELLIO also says it reproduced shell access on x86-64 against plain node:http, the node:24.22.0-slim image, Express 5.3.0 and Koa 3 with ASLR on (10,000 attempts per ELLIO), but that the memory offset for 24.22.0 did not work against 22.23.3 or 26.12.0. ELLIO’s lab also saw hangs in other decoders (Python brotli, brotlicffi, PHP streaming, the Ruby gem). Aikido reports that the first public PoC (October 22) reached code execution only against a deliberately weakened build, and that researchers later achieved it on an unmodified 24.22.0 arm64 image, though not on every attempt; Aikido’s account puts that success on the same day, and ELLIO credits Imperva Red Team (we did not open Imperva’s write-up). Aikido attributed “no exploitation in the wild as of October 22” to The Hacker News. We found no evidence as of 2026-10-28 in Node.js, Aikido, ELLIO, GHSA, NVD or KEV of a named actor, a campaign or a confirmed compromised victim. ELLIO’s in-the-wild observations are sensor hits, not confirmed victims. ELLIO also says the in-the-wild chain redirects stdin only, so commands go in and nothing comes out; that is single-vendor.

Impact Assessment

ELLIO’s lab saw most of its four hundred Express attempts crash the worker, and core dumps may disclose memory. Our inference from that: denial of service is the realistic floor for exposed Node.js services. Reliable code execution needs build-specific offsets, which raises the bar but, per the telemetry above, has not stopped attempts. Internet-facing Express 5 services that accept Brotli request bodies, and services that fetch Brotli responses from untrusted servers, are the first to patch.

Affected Versions

ComponentAffectedFixed
Google Brotli (NVD)1.0.3 through 1.2.01.0.10, 1.1.1, 1.2.1
Node.js22.x, 24.x, 26.x22.23.4, 24.22.1, 26.12.1
Bunbefore 1.4.4 (single-source)1.4.4
PyPI brotli / brotlicffi1.0.3 to before 1.2.1 / 1.2.1.01.2.1 / 1.2.1.0

The Node.js advisory lists releases 22.23.4, 24.22.1 and 26.12.1 (dated October 21), rates the issue “high”, says it affects the 26.x, 24.x and 22.x lines and credits OpenAI Codex Security. The per-line mapping is our inference from the page layout, matching Aikido and ELLIO. The Bun 1.4.4 fix version rests on Aikido and ELLIO only: Bun issue 46352 confirms Bun was affected, but the 1.4.4 release notes do not mention Brotli. Node.js 20.x, 23.x, 25.x and earlier are end of life with no fix (per Aikido and ELLIO). Distro-packaged Node.js may use the system Brotli library instead, so check your distribution’s advisory.

CVSS: Google’s CNA scores CVSS 4.0 at 9.2 (AV:N/AC:L/AT:P/PR:N/UI:N, high VC/VI/VA). NVD had not added its own score when we looked (status “Undergoing Analysis”). The Node.js project labels it “high”, one step below critical.

Remediation Steps

  1. Run node --version on hosts and CI runners, and docker run --rm <image> node --version for images.
  2. Upgrade Node.js to 22.23.4, 24.22.1 or 26.12.1, then rebuild and redeploy images. Move off end-of-life lines.
  3. Upgrade Bun to 1.4.4 or later, PyPI brotli to 1.2.1 and brotlicffi to 1.2.1.0, and any bundled Brotli to 1.0.10, 1.1.1 or 1.2.1.
  4. Check vendored copies and bun build --compile executables, which keep the old decoder until rebuilt.
  5. Stopgap only, per Aikido and ELLIO: reject or strip inbound Content-Encoding: br at a proxy or middleware. This does not cover Brotli responses your code fetches from other servers, and the Node.js advisory offers no workaround.
  6. Limit core dump access and retention.

Detection Guidance

Searching for exposure: npm ls express body-parser, and code search for brotliDecompress and createBrotliDecompress. List outbound fetch() calls to servers you do not control.

Traffic signals from ELLIO: inbound requests with Content-Encoding: br, very large Brotli bodies, the user agent above, and the body hash and IP in the exploitation section. On patched builds, malformed input yields a 400 with ERR__ERROR_FORMAT_BLOCK_SWITCH. Unexplained Node.js worker crashes after Brotli requests are a signal on unpatched hosts. ELLIO published no IDS, YARA or WAF signatures in its post; Aikido reports Vercel platform firewall rules (October 21) that block the attack in inbound requests; we found no other rules as of 2026-10-28 in the sources read.

Timeline

DateEvent
2026-06-13ELLIO first observes the checker’s address (per ELLIO)
2026-10-21Brotli 1.2.1 release dated; Node.js security releases published
2026-10-22NVD and GitHub advisory published; first public PoC (per Aikido)
2026-10-26ELLIO observes the 23 MB exploit body
2026-10-27CISA adds CVE-2026-111497 to KEV
2026-11-10CISA KEV due date

References