Skip to content
Back to Blog
Vulnerability ManagementFeatured

Node2Shell: A Brotli Vulnerability That Could Turn a Crash Into Code Execution (CVE-2026-111497)

Preservers Research
October 25, 2026
8 min read

Node2Shell: A Brotli Vulnerability That Could Turn a Crash Into Code Execution

A critical vulnerability in the Brotli decompression engine—tracked as Node2Shell (CVE-2026-111497)—highlights an urgent and often overlooked security risk in modern runtime environments: untrusted data crossing low-level compression boundaries.

Node2Shell: Brotli Out-of-Bounds Write Architecture and Runtime Triage

Node.js, Bun, and hundreds of web frameworks bundle Google Brotli natively to accelerate HTTP payload transfer and decompress client requests (Content-Encoding: br). When an application decompresses a specially crafted, attacker-controlled Brotli stream, an out-of-bounds write occurs in the underlying C/C++ engine, allowing threat actors to manipulate heap layout and potentially achieve arbitrary remote code execution.

Here is what engineering teams, security operations, and platform architects need to understand about Node2Shell, how to verify exposure, and what immediate runtime upgrades to deploy today.

---

1. What Is Node2Shell? The Technical Breakdown

The underlying issue affects Google Brotli versions 1.0.3 through 1.2.0. Because major JavaScript/TypeScript runtimes statically link or vendor Brotli into their standard libraries (such as zlib.createBrotliDecompress() in Node.js core), any vulnerability in Brotli instantly manifests as a first-class runtime vulnerability.

The Vulnerability: Out-of-Bounds Heap Write

Brotli uses specialized sliding-dictionary windows, prefix coding, and context modeling to achieve high compression ratios. During the decoding of a corrupted or weaponized stream:

  1. Malformed Stream Input: An attacker crafts a compressed payload featuring malicious distance symbols, invalid Huffman tree configurations, or out-of-range backward reference offsets.
  2. Boundary Validation Failure: The Brotli decoder fails to strictly validate the destination memory boundaries before writing reconstructed byte sequences into the output ring buffer.
  3. Out-of-Bounds Write: Decoded bytes are written past the allocated buffer bounds directly into adjacent heap memory allocations.

The Exploit Triad: Three Levels of Impact

Depending on the host application architecture, memory protections (ASLR, DEP), and how the runtime manages buffer allocations, the vulnerability exposes applications to:

  • ⚠️ Application Crashes & Denial of Service (DoS): An out-of-bounds write that faults on unmapped pages or corrupts runtime metadata triggers immediate segmentation faults (SIGSEGV or SIGABRT), taking down Node.js or Bun processes instantly.
  • ⚠️ Memory Disclosure: Corrupting adjacent buffer lengths or sliding window pointers can lead to reading out uninitialized heap contents, leaking sensitive tokens or co-located HTTP request data back into application responses.
  • ⚠️ Remote Code Execution (RCE): In environments where attackers can predict heap layouts or overwrite internal function pointers (such as libuv handles or V8 heap objects), the flaw can turn an unauthenticated crash into arbitrary code execution on the server.

---

2. Are Your Node.js & Bun Environments Affected?

Because compression libraries operate below application-layer input validation, any service that accepts and decompresses external Brotli data is directly exposed.

Runtime Patch Matrix

RuntimeAffected Release LinesFixed Upstream ReleaseAction Required
Node.js 26.xPrior to 26.12.1Upgrade to 26.12.1 or laterImmediate upgrade
Node.js 24.x (LTS)Prior to 24.22.1Upgrade to 24.22.1 or laterImmediate upgrade
Node.js 22.x (LTS)Prior to 22.23.4Upgrade to 22.23.4 or laterImmediate upgrade
Node.js 20.x, 23.x, 25.xAll versionsNo fix listed (End-of-Life)Migrate immediately to Node 22.x or 24.x LTS
BunVersion 1.4.3 and earlierUpgrade to 1.4.4 or laterUpgrade Bun binary
Google Brotli (C/C++)Versions 1.0.3 through 1.2.01.0.10, 1.1.1, and 1.2.1Rebuild native packages across branches
🚨 Critical EOL Notice: If your services still run Node.js 20.x (or older release lines like 18.x or odd-numbered releases like 23.x/25.x), no official upstream patch will be released. You must migrate to a supported active LTS line (Node.js 22.x or Node.js 24.x) to resolve the vulnerability.

---

3. High-Risk Exposure Vectors: Where Does Brotli Execute?

Organizations frequently assume they do not use Brotli because they do not call zlib.brotliDecompress() explicitly in application business logic. However, Brotli decompression is routinely triggered implicitly across:

  1. API Gateways & Reverse Proxies: Reverse proxies or microservices written in Node.js (e.g., using Fastify, Express with compression or body-parser, or custom middleware) that automatically decompress incoming HTTP POST/PUT bodies marked with Content-Encoding: br.
  2. Content Processing Pipelines: Microservices ingesting, storing, or indexing uploaded documents, archives, or webhooks compressed with Brotli.
  3. Data Ingestion & Event Stream Consumers: Node.js workers consuming compressed Kafka, SQS, or RabbitMQ messages where untrusted producers can supply arbitrary payloads.
  4. Third-Party Crawlers & Web Scrapers: Headless browser automation or scraper microservices handling compressed HTTP response payloads from arbitrary external servers.

---

4. What Security & Platform Teams Must Do Now

Follow this actionable 5-step response protocol:

Step 1: Inventory Node.js & Bun Runtimes Across All Estates

Scan production hosts, Kubernetes worker nodes, serverless containers (AWS Lambda, Google Cloud Run), and CI/CD base images:

```bash

# Check current Node.js runtime version:

node -v

# Check bundled Brotli library version in Node.js:

node -p "process.versions.brotli"

# Check Bun runtime version:

bun -v

```

Step 2: Identify Ingestion Boundaries Handling Untrusted Brotli Streams

Audit application code for direct or indirect decompression of untrusted input:

  • Search codebases for usages of createBrotliDecompress, brotliDecompress, or brotliDecompressSync.
  • Inspect reverse proxies and HTTP middleware that automatically handle Content-Encoding: br.
  • If decompression of untrusted Brotli input is not required, temporarily disable or reject incoming requests specifying Content-Encoding: br at the ingress controller (e.g., Cloudflare WAF, AWS ALB, or Nginx) until runtimes are updated:

```nginx

# Reject incoming requests with Brotli compression if unneeded

if ($http_content_encoding ~* "br") {

return 415;

}

```

Step 3: Upgrade to Patched Runtimes & Verify Dependencies

Update base Dockerfiles and deployment manifests:

```dockerfile

# For Node.js 22 LTS:

FROM node:22.23.4-alpine

# For Node.js 24 LTS:

FROM node:24.22.1-alpine

```

Ensure your CI/CD pipelines rebuild images from updated base distributions rather than relying on stale cached layers.

Step 4: Prioritize Internet-Facing Applications First

Triage systems by exposure level:

  1. Tier 1 (Immediate): Publicly accessible API gateways, web applications, and webhook ingestion endpoints.
  2. Tier 2 (High): Backend message consumers processing multi-tenant data pipelines.
  3. Tier 3 (Medium): Internal developer tools, CI test runners, and batch processing cron jobs.

Step 5: Add Regression Tests & Monitor for Crash Signatures

  • Configure monitoring alerts for sudden spikes in SIGSEGV or SIGABRT process crashes across your container fleet.
  • Run regression suites with fuzz-tested inputs to confirm that decompression pipelines handle malformed streams gracefully without process termination.

---

5. The Bigger Lesson: The Compression Boundary Paradox

A vulnerability in a low-level compression library becomes an application-level security emergency the moment untrusted data crosses the boundary into a vulnerable decoder.

Modern software stacks increasingly rely on runtimes that bundle native C/C++ libraries under the hood. While JavaScript and TypeScript provide memory-safe application semantics, their native bindings into libraries like Brotli, OpenSSL, or SQLite inherit the full spectrum of low-level memory hazards.

Patching is essential, but knowing where the vulnerable component exists, what is exposed to untrusted inputs, and what to fix first is the cornerstone of effective security posture.

Continuous Attack Surface & Exposure Management with Preservers: Not sure which of your external domains, API gateways, or container clusters expose vulnerable Node.js runtimes or unpatched native libraries? Run a free exposure report with Preservers to continuously discover and prioritize external vulnerabilities across your digital perimeter.

Share this article