CVE-2026-111497 (Node2Shell): what the edge does and what you must still patch

The edge refuses Brotli-encoded request bodies with shield 1009. It doesn't patch your servers or the responses your code fetches; update Brotli.

On this page

CVE-2026-111497, also called Node2Shell, HTTP2Shell or Brotli2Shell, is an out-of-bounds write in Google's C Brotli decoder (DecodeBlockTypeAndLength in c/dec/decode.c). It is fixed in Brotli 1.2.1. A crafted Brotli stream can give an attacker remote code execution in any process that decodes it. It has a CVSS score of 9.2, it has been in the CISA Known Exploited Vulnerabilities catalog since 2026-10-27, and it is being exploited.

You are exposed in two ways:

  • Servers that decode request bodies sent with Content-Encoding: br: Express 5 / body-parser 2.x (raw(), json()…) on Node.js before 22.23.4, 24.22.1 and 26.12.1, ASP.NET Core request decompression, the ClickHouse HTTP interface, Python services that use brotli or brotlicffi, and the PHP brotli extension.
  • HTTP clients that decode Brotli responses: Node.js fetch(), .NET HttpClient, and Python requests, httpx, aiohttp or urllib3 when brotli is installed. A server the attacker controls only has to answer with a crafted body.

What the edge does

The edge has a new shield, 1009 «Brotli Request Body». It refuses every request that has a body whose Content-Encoding lists br, before the request reaches your origin. The header is matched in any case, and br is found anywhere in the list: gzip, br or across several Content-Encoding lines. The request gets a 403 with your block page. The edge doesn't decode request bodies to look for the exploit.

Nothing else changes:

  • requests without a body, and bodies encoded with gzip, deflate, zstd or identity, pass as before;
  • responses aren't touched;
  • browsers never send Brotli request bodies, so visitors aren't affected.

Like every shield, 1009 follows the site's mode: it blocks in active, only records in log (the request reaches the origin) and doesn't run when the WAF is off.

The edge's own Brotli decoder is a Go port. It has the same logic bug but no memory corruption (in Go it was a crash, GHSA-c9gr-gmg4-2vqv). It has been updated, and an error while decoding now only ends that stream.

If your application receives Brotli request bodies

Some APIs legitimately accept bodies compressed with Brotli, for example an ingestion endpoint fed by your own agents. Patch that origin first (below), then add a WAF exception for rule 1009 on that path only, limited to the name that needs it. An exception with rule_id 0 does not switch the shield off.

Domain → Security → Firewall → Rules → WAF exceptions → Add WAF exception. Enter 1009 as the WAF rule, the Path (for example /v1/ingest), the name in Applies to and a Note.

What the edge doesn't cover

  • Responses your code fetches. If your servers or scripts call fetch() or another HTTP client on a URL an attacker can choose, the crafted Brotli response goes straight to them. The edge only sees requests to your proxied names.
  • Traffic that skips the edge. Anyone who reaches your origin directly, by its IP address or another name, isn't inspected. Accept connections only from the OpenWAF edge and use Full (strict) origin TLS.
  • Names that aren't proxied, sites in log mode and sites with the WAF off.
  • Other ways of feeding Brotli data to your software: uploaded files, queues, message brokers, files in storage.

What you must patch

SoftwareFixed in
Node.js22.23.4, 24.22.1 or 26.12.1 and later. Lines that are end-of-life get no fix: move to a supported line. Check node -v inside your container images too, not just on the host.
Python brotli / brotlicffiThe releases built on Brotli 1.2.1.
PHPThe php.net releases of 2026-10-26.
.NETThe October 2026 servicing update.
libbrotli from the OSYour distribution's security update; then restart the services that load it.
Anything else that embeds Brotli before 1.2.1Its patched release: FFmpeg, libjxl, ClickHouse, Apache Arrow and others.

Check whether you were targeted

Refused requests appear in security events with rule_id 1009 and rule_name Brotli Request Body. In Analytics › Traffic → Security events, select Add filter → Rule is 1009, or ask the API:

curl -s "https://dash.openwaf.dev/v1/orgs/$ORG/zones/$ZONE/events?rule_id=1009&since=2026-10-27T00:00:00Z" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"

An event before you patched only tells you that someone tried through the edge. It doesn't tell you whether your origin was reached another way. Check the origin's own logs too.

Sources

Last updated:

↑↓ to navigate↵ to openesc to close