Security
Oct 23, 2026

CVE-2026-111497 (Node2Shell): Node.js Brotli RCE, EOL Risk

Node2Shell (CVE-2026-111497) is an out-of-bounds write in the Brotli decoder compiled into Node.js. See the fixed versions and why EOL lines stay exposed.

Give me the TL;DR
CVE-2026-111497 (Node2Shell): Node.js Brotli RCE, EOL Risk

On October 21, 2026, the Node.js project fixed CVE-2026-111497, since nicknamed Node2Shell, in its October 2026 security release. It is an out-of-bounds write in the Brotli decoder compiled into the Node.js binary. Fixed versions are 26.12.1, 24.22.1, and 22.23.4. 

‍

Every end-of-life line we checked, from 20.x back to 12.x, bundles the vulnerable decoder and has no OSS upstream fix available. HeroDevs will ship remediated Never-Ending Support (NES) builds for end-of-life Node.js starting with 20.x, followed by 18.x, then the remaining affected end-of-life lines.

‍

Affected and unsupported? See NES for Node.js coverage for your version.

What is CVE-2026-111497?

CVE-2026-111497 is an out-of-bounds write (CWE-787, rooted in an unchecked return value, CWE-252) in Google's Brotli library, affecting 1.0.3 through 1.0.9, 1.1.0, and 1.2.0; Google fixed it in Brotli 1.0.10, 1.1.1 and 1.2.1. Google, as the CVE Numbering Authority (CNA), scores it 9.2 on CVSS 4.0; the Node.js project rates its impact on the runtime as High.

Node.js vendors its own copy of that library under deps/brotli, so the flaw is a property of the runtime binary, not of any npm package. (The npm package named brotli is a separate project and is not the vulnerable component.)

Node.js runs the bundled decoder any time it decompresses Brotli data. That happens explicitly through the node:zlib Brotli APIs (zlib.brotliDecompress(), zlib.brotliDecompressSync(), zlib.createBrotliDecompress()) and implicitly in two places most teams do not think of as "decompression code": the built-in fetch(), which transparently decodes responses sent with Content-Encoding: br, and body-parsing middleware that inflates compressed request bodies. Those two implicit paths turn a library bug into a broad attack surface, because most teams do not think of them as decompression code at all.

What a successful attack yields

  • Denial of service. The floor outcome is a segmentation fault that kills every in-flight request on the worker, repeatable after each restart.
  • Memory disclosure. A partial read primitive can expose request data, tokens, and configuration resident in the heap.
  • Code execution as the Node.js process user. Environment variables, mounted secrets, database credentials, cloud instance metadata and the IAM credentials behind it, and internal services on the same network all come into reach.

Node2Shell exploitation status

Public exploitation research moved within a day of the fix:

  • A first public proof of concept appeared on October 22, 2026. According to The Hacker News, it reached code execution only against a deliberately weakened test build; on a standard build its author reported a crash and a limited memory read.
  • The same day, the Imperva Red Team, whose analysis gave the flaw its Node2Shell name, reported code execution on the official, unmodified Node.js 24.22.0 image for Linux arm64, reaching the decoder through fetch() and through Express 5 with body-parser 2.x. The exploit was not reliable on every attempt, and other architectures and the 22.x and 26.x lines were not tested. Node.js 24.22.1 rejected the same input.

CVE-2026-111497 is not in the CISA Known Exploited Vulnerabilities catalog (catalog version 2026.10.23, checked October 23, 2026). CISA's SSVC enrichment on the CVE record lists exploitation as none, automatable as no, and technical impact as total. No exploitation in the wild had been reported as of October 23, 2026.

Node.js End-of-Life Lines Inherit This CVE Permanently

The Node.js advisory names 26.x, 24.x, and 22.x because those are the lines it supports. The project’s advisory states that end-of-life versions are always affected when a security release occurs. HeroDevs confirmed that in the code.

Node.js version support dates are published by the project. Node.js 22 reaches end of life on April 30, 2027.

Exposure requires two conditions: a runtime below the fixed version, and a path for attacker-controlled Brotli data to reach the decoder.

What HeroDevs verified in the code

HeroDevs experts, including active Node.js contributors, read  deps/brotli/c/dec/decode.c at the final release tag of every end-of-life line. In Node.js 25.9.0, 23.11.1, 21.7.3, 20.20.2, 18.20.8, 16.20.2, 14.21.3, 12.22.12, and 10.24.1, DecodeBlockTypeAndLength() still returns BROTLI_FALSE for the single-block-type case, and neither BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH nor BROTLI_SAFE_WITH_STATUS() is present. The bundled Brotli versions (1.1.0 in 20.x and 18.x, 1.0.9 in 16.x through 12.x) all fall inside the CNA's affected range. 

HeroDevs also confirmed that the built-in fetch() (undici) in Node.js 20.20.2 and 18.20.8 decodes Content-Encoding: br responses through zlib.createBrotliDecompress(). The outbound-fetch attack path is live on those lines exactly as it is on supported ones, and Express 5, which supports Node.js 18 and later, puts the inbound request-body path on them as well.

CVE-2026-111497 mitigation guidance

Upgrading within a supported line is a patch-level change with no API break. Moving off an end-of-life line is a different project, often involving native module rebuilds, OpenSSL behavior changes, and dependency conflicts, and that gap is what remediated end-of-life builds are meant to close.

Related CVEs in the October 2026 Node.js security release

CVE-2026-111497 shipped as one of ten CVEs in the October 21, 2026 Node.js security release. Four share Node2Shell's theme: services that connect to hosts users can influence. The siblings worth tracking alongside it are:

  • CVE-2026-106069: High-severity TLS hostname bypass where tls.checkServerIdentity() matches a loosely written IP address against a certificate for a different endpoint. It affects 26.x, 24.x, and 22.x and, like Node2Shell, matters most for services that open connections to user-supplied hosts.
  • CVE-2026-105482: High-severity DNS flaw where dns.resolve*() and dns.reverse() truncate names at an embedded NUL byte, so an allowlist check and the actual query can disagree. An incomplete fix of CVE-2026-48930.
  • CVE-2026-105483: High-severity TLS hostname bypass using fullwidth digits in an IPv4 host, affecting 24.x and 26.x.
  • CVE-2026-106072: Medium-severity certificate validation flaw where a DNS-only SAN can authenticate a non-canonical IPv4 endpoint, fixed in the same commit as CVE-2026-106069.

For previous Node.js releases and the end-of-life angle, see our breakdown of the July 2026 Node.js security release, our analysis of CVE-2026-56848, the HTTP/2 RST_STREAM use-after-free, and Node.js 20 goes EOL: how to stay secure without a full migration.

What to Do Now

On a supported line, upgrade to 26.12.1, 24.22.1, or 22.23.4, rebuild every image and executable that embeds the runtime, and restart the processes. Start with services that inflate request bodies or fetch user-supplied URLs.

On an end-of-life line, the question is not whether you are affected; HeroDevs has read the code, and you are. The question is how long you intend to run a runtime that decodes attacker-supplied Brotli through fetch() by default, and through common body-parsing middleware on request bodies, and will never receive an upstream fix.

Node2Shell will be patched and forgotten on supported lines within weeks. On end-of-life lines it becomes a forever-day: a public, weaponizable flaw with no upstream fix, ever. HeroDevs, an official Node.js partner for Never-Ending Support, is closing that gap with remediated drop-in builds. Check NES for Node.js coverage for your version and resolve CVE-2026-111497 without forcing a migration on someone else's timeline.

Talk to our team about NES for Node.js.

Frequently Asked Questions

What is Node2Shell?

Node2Shell is the nickname for CVE-2026-111497, an out-of-bounds write in the Brotli decoder bundled inside Node.js. A crafted Brotli stream can crash the process, leak memory, or, in a demonstrated proof of concept, execute code.

Which Node.js versions fix CVE-2026-111497?

Node.js 26.12.1, 24.22.1, and 22.23.4 fix it. Every earlier release on those lines is affected, as is every end-of-life line from 25.x back to 12.x.

Is Node.js 20 affected by CVE-2026-111497?

Yes. HeroDevs confirmed the vulnerable decoder in Node.js 20.20.2, the final 20.x release, and Node.js will not patch it because 20.x reached end of life on April 30, 2026. NES for Node.js remediation for 20.x is in progress.

Does updating the npm Brotli package fix Node2Shell?

No. The vulnerable code is compiled into the Node.js runtime under deps/brotli; the npm package named brotli is unrelated. Only a fixed runtime build removes the flaw.

Am I exposed if my app never calls zlib?

Possibly. The built-in fetch() decodes Brotli responses automatically, and Express 5 with body-parser 2 inflates Brotli request bodies, the two paths Imperva demonstrated. Other body-parsing middleware that honors Content-Encoding: br exposes the same decoder.

‍

‍

Table of Contents
Author
Javier Perez
Technical Product Owner & Manager - Javascript
Open Source Insights Delivered Monthly