Security Bulletin

Node2Shell / HTTP2Shell (CVE-2026-111497): Brotli Library RCE

5 min read Updated

On October 21, 2026, Node.js fixed CVE-2026-111497, a critical vulnerability now known as Node2Shell and, since October 24, HTTP2Shell. The vulnerability is in Google’s Brotli library itself, the decoder that unpacks Brotli-compressed data. Node.js shipped the first runtime fix. Bun, Python’s Brotli packages, Envoy, Istio and Electron are also affected because they use the same library.

A crafted compressed stream makes the decoder write data outside the memory set aside for it, known as an out-of-bounds write. That can overwrite data the application relies on, so an attacker can crash the application, leak memory or run attacker code. Public proof-of-concept code was published within 24 hours. AppTrana WAAP blocks the inbound attack path for any backend behind it. Patching is still required to close the paths a WAF cannot see.

Risk Analysis

SeverityCritical
CVSS Score
CVSS 4.0 score of 9.2
Vendor ratingRed Hat rates it Important
ImpactRemote code execution possible
Attack Vector(AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H)
Exploitation StatusPublic PoCs since October 22. Researchers achieved code execution on the official Node.js 24.22.0 image, though it was unreliable and took several attempts. No in-the-wild attacks reported. Not in CISA’s KEV catalog as of October 26, 2026. CISA assesses it as not automatable.

Affected versions

Google Brotli 1.0.3 to 1.2.0, and the runtimes and packages that use it

Fixed VersionsBrotli 1.0.10, 1.1.1 and 1.2.1. See the affected versions table for runtimes and packages.

Node2Shell: From Patch to Public PoC in 24 Hours

February 27, 2026

The Brotli fix lands upstream, with no security note.

October 21, 2026

Node.js releases 22.23.4, 24.22.1 and 26.12.1.

October 22, 2026

The CVE is published with a CVSS score of 9.2. Public PoCs appear. They crash and leak memory on standard builds.

October 23, 2026

Researchers demonstrate code execution on the official Node.js 24.22.0 image. Envoy publishes its advisory. Python Brotli 1.2.1 and brotlicffi 1.2.1.0 are released.

October 24, 2026

Bun names the vulnerability HTTP2Shell.

What is Node2Shell (HTTP2Shell)?

Node2Shell is a memory-safety vulnerability in Google’s Brotli decoder library, versions 1.0.3 to 1.2.0. Node.js bundles this library in its zlib module, and many other runtimes, proxies and packages use it.

An attacker crafts a Brotli stream that is deliberately malformed: it declares one type of data block, then asks the decoder to switch block types. The decoder should stop with an error. An unpatched decoder ignores the error and keeps going, so it writes past the end of its buffer. The fix (Brotli commit 0ed4268a) stops decoding with a new error, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH.

An attacker needs an application to decompress Brotli data that the attacker controls. This can happen in four ways:

Request bodies

The attacker sends a Brotli-compressed request body, marked with the Content-Encoding: br header. Express 5.0.0 to 5.3.0, body-parser 2.0.0 to 2.3.0 and Koa decompress these by default.

Outbound responses

The application calls a server the attacker controls, and the server replies with a Brotli response. Built-in fetch(), Next.js server-side fetch(), axios, node-fetch, got and SuperAgent decompress it automatically. In Python, requests, urllib3, httpx and aiohttp decode Brotli automatically when Brotli or brotlicffi is installed.

Application code

The application passes attacker-supplied files or fields to zlib.brotliDecompress() or an equivalent Brotli call in another language.

Proxies

The application runs behind Envoy or Istio with the Brotli decompressor turned on. The proxy decodes the Brotli data itself, so the attack reaches the proxy before it reaches the application.

Affected and Fixed Versions

Product Vulnerable Fixed
Google Brotli library 1.0.3 – 1.2.0 1.0.10 / 1.1.1 / 1.2.1
Node.js 22.x < 22.23.4 22.23.4
Node.js 24.x < 24.22.1 24.22.1
Node.js 26.x < 26.12.1 26.12.1
Node.js 20.x, 23.x, 25.x and older All No fix (end of life). Upgrade to 22, 24 or 26
Bun ≤ 1.4.3 1.4.4
Python Brotli ≤ 1.2.0 1.2.1
Python brotlicffi ≤ 1.2.0.x 1.2.1.0
Envoy (with Brotli decompressor) Below the fixed versions 1.36.12 / 1.37.8 / 1.38.6 / 1.39.3 / 1.40.0
Istio (with Brotli decompression) 1.29.0 – 1.31.1 1.29.9 / 1.30.6 / 1.31.2
Ruby brotli gem < 0.9.1 0.9.1

Some Linux distributions and runtimes are still waiting for a fix. Red Hat Enterprise Linux 8, 9 and 10, the .NET runtime, the PHP Brotli package, and the Debian and Ubuntu nodejs packages have no patch yet. Amazon Linux 2023 has fixed its brotli and nodejs24 packages, though its nodejs and nodejs20 packages have no fix planned. Debian 12 and 13 and Alpine have also shipped fixed brotli packages.

Keep in mind that Node.js and Bun bundle their own copy of Brotli, so updating the OS package does not protect them. Upgrade the runtime itself.

What Node2Shell Means for Your Web Infrastructure

Risk What it means
Server takeover An attacker’s code runs with the permissions of the affected process (Node.js, Bun, Python or Envoy) and can steal data.
Stolen credentials Even when code execution fails, leaked memory can expose database credentials, API keys and cloud tokens.
Service outage Each failed attempt can crash the process and take an API offline.
Attack through outbound calls Webhooks, link previews, crawlers and AI agent tools fetch URLs that other people choose. A malicious server can reply with a crafted Brotli response that no inbound control sees. This applies to Node.js and Python HTTP clients alike.

How to Detect Node2Shell

Find every Node.js, Bun, Python, Envoy, Istio and Electron runtime, including containers and CI. Then look for these signs from October 21 onwards:

Requests

Any Content-Encoding: br request body, which browsers and API clients do not send. Watch most for bodies over 1 MB or sent chunked (the published PoC is about 23 MB), duplicate Content-Encoding headers, and repeated Brotli requests from one IP.

Outbound traffic

Brotli responses from hosts that users supply, such as webhook targets, link-preview URLs and AI agent tool calls.

Logs

ERR__ERROR_FORMAT_BLOCK_SWITCH (constant BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH, value -17) means a patched runtime rejected an attack attempt. On unpatched servers, look for Brotli decoding errors, SIGSEGV crashes in Node.js, Bun, Python or Envoy, restarts and HTTP 502/503 after a Brotli request.

Host activity

Node.js, Bun, Python or Envoy processes starting sh, bash, curl or wget, and unexpected outbound connections.

A crash alone does not prove exploitation. Check patched servers too, since patching does not remove an earlier compromise.

Node2Shell: Mitigation and Remediation

Upgrade Node.js to 22.23.4, 24.22.1 or 26.12.1, Bun to 1.4.4, Python Brotli to 1.2.1, brotlicffi to 1.2.1.0, and Envoy and Istio to the fixed versions listed above. Rebuild container images with docker build --pull, restart services, and rotate secrets if you find signs of compromise. Until you can patch, these settings reduce exposure:

// Confirm the fix (run in a shell): prints -17 when patched
node -p "require('zlib').constants.BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH"

// Express 5: stop decoding compressed request bodies
app.use(express.json({ inflate: false }));

// axios / got: turn off response decompression
axios.get(url, { decompress: false });

Python: Upgrade Brotli and brotlicffi, or uninstall them where they are optional. requests, urllib3, httpx and aiohttp stop requesting Brotli when neither package is installed.

Envoy and Istio: Upgrade, or turn off the Brotli decompressor until you can.

A WAF blocks the inbound path, but it cannot see Brotli responses your application fetches. Patching is the only complete fix.

AppTrana WAAP Coverage for Node2Shell

AppTrana WAAP customers are protected against inbound Node2Shell attacks on any backend, including Node.js, Bun, Python and Envoy. Protection is in block mode by default, with no action needed.

Emergency rule update (October 22, 2026)

AppTrana blocks Brotli-compressed request bodies (Content-Encoding: br, including variants such as gzip, br) and duplicate Content-Encoding headers before they reach the origin. The rule protects any backend behind AppTrana, including Node.js, Bun, Python, Envoy and Istio. The Indusface security research team released the rules to all AppTrana sites after validating them for false-positive risk.

Continuous monitoring

The 24×7 managed services team tracks Node2Shell rule hits, obfuscated br values and PoC-sized streams across all customers.

Recommended actions for AppTrana customers

Keep applications in Block mode, enable Origin Protection, and upgrade every affected runtime and package. AppTrana protects you while you patch; outbound fetch() responses still need the runtime fix.

Protect Node.js, Bun, Python and Envoy workloads with AppTrana WAAP.

Block inbound Node2Shell attack attempts while your team patches every runtime.

See AppTrana in Action

References

Pavithra Hanchagaiah

Passionate InfoSec Pro with 18+ yrs experience in R&D, Project Mgmt, & Tech Leadership. Head of Security Research at Indusface's AppTrana, leading teams delivering WAS & WAF mechanisms. Former Manager at TrendMicro, leading cross-functional teams in IPS/IDS signature development. Expertise in team leadership, process improvement, and issue analysis