Brotli goes RCE: patch CVE-2026-111497 today
By Arash Latifi
The Brotli flaw behind Node2Shell now affects HTTP clients across languages (HTTP2Shell) — patched versions and an upgrade checklist.
TL;DR — CVE-2026-111497 started as "Node2Shell" and grew into "HTTP2Shell": Node.js, Python packages, curl, Bun, Envoy and Istio all bundle the same vulnerable Brotli decoder. Upgrade to patched releases today.
On Wednesday, October 21, the Node.js team disclosed a serious flaw in the Brotli decoder bundled with Node: malformed compressed input can corrupt process memory, leak memory, or lead to remote code execution. By Friday it became clear this is far bigger than Node — almost every piece of software that decompresses Brotli shares the same decoder code.
The bug
CVE-2026-111497 is an out-of-bounds write in the Google Brotli decoder affecting versions 1.0.3 through 1.2.0 on all platforms, with a CVSS v4.0 score of 9.2 (Critical).
The mechanics are simple: when a Brotli stream is malformed, the decoder should reject it immediately. In one specific case (an invalid block switch) it instead reports a temporary need for more input and keeps appending bytes to an eight-byte internal buffer — until it overflows. An attacker who can supply attacker-controlled Brotli data can use that corruption to run their own code.
The painful backstory: OpenAI found this in February 2026 and the root cause was fixed in the Brotli source at the time — but it wasn't recognized as a security issue, so no release ever shipped with the fix. Every project bundling Brotli has to ship its own update. The reporters credited in the Node advisory are OpenAI Codex Security (Khai Tran and Sylvie Mayer).
It's dangerous in both directions: a malicious client can take over an unpatched server, and a malicious server can take over an unpatched client that accepts compressed responses.
Blast radius: not just Node
Aikido dubbed this wave "HTTP2Shell" because so many languages and tools share the same decoder:
- Node.js 26.x, 24.x, 22.x — via the bundled Brotli library
- Python — the
Brotliandbrotlicffipackages, whichrequests,httpx, andaiohttpload automatically when installed - Bun, Envoy, Istio, curl/libcurl — and any binary statically linking libbrotli
- Good news: Apache's
mod_brotliand Nginx do not decode Brotli by default
One nasty catch: as of October 23, advisory databases hadn't mapped the CVE to the PyPI packages — meaning pip-audit, Dependabot, and Safety won't flag vulnerable versions yet. You have to check manually.
Patched versions
| Project | Fixed versions | | --- | --- | | Node.js | 22.23.4 / 24.22.1 / 26.12.1 | | Brotli (upstream) | 1.2.1 (or 1.0.10 / 1.1.1 for older branches) | | Python: Brotli / brotlicffi | 1.2.1 / 1.2.1.0 | | Bun | 1.4.4 | | Envoy | 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 | | Istio | 1.29.9 / 1.30.6 / 1.31.2 |
Check and patch
If your Python app doesn't actually need Brotli, the fastest hardening step is removing it entirely:
httpx and requests keep gzip and deflate support without these optional packages — you'd only see an unreadable response if a server sends Brotli anyway.
- [ ] Checked
node -vand I'm on a patched line - [ ] Checked/updated Python
Brotliandbrotlicffiin all environments (including Docker) - [ ] Rebuilt and restarted Docker images
- [ ] Rebuilt compiled executables (Bun, statically linked binaries)
- [ ] Confirmed remediation with managed-service providers
- [ ] Watching advisories — this is still expanding
Three more CVEs in the same Node release
Brotli wasn't alone; the October 21 Node release also fixed three other high-severity issues:
- CVE-2026-105482:
dns.resolve*()silently truncates hostnames containing a NUL byte — soattacker.example\0.trusted.exampleresolvesattacker.examplerecords, letting an attacker bypass domain allowlists. - CVE-2026-105483: TLS hostname verification bypass via fullwidth digits like
127.0.0.1— a certificate for DNS:127.0.0.1 could be accepted for an IP it wasn't issued for. - CVE-2026-106069: leading-zero IPs like
0127.0.0.1— one component reads it as octal, another as decimal, so a certificate for the wrong IP validated.
If the Brotli fix alone wasn't enough reason to update your Node release line, these three are.
Q: My app only renders JSON and never decompresses user input. Am I vulnerable?
Direct exploitation is less likely, but not zero: any client that accepts Brotli-compressed HTTP responses is exposed to a malicious server. Updating to a patched release costs nothing — just do it.
Q: Why didn't my dependency scanner flag this?
Because as of October 23 the advisory databases hadn't mapped the CVE to the PyPI packages, and Node's advisory only fills in after the release. For fresh CVEs, scanners are always a day late.
Q: What do I do until I can fully upgrade?
Priority one: move Node to a patched line. In Python, uninstall Brotli/brotlicffi if they're optional. If a service has no patch and decodes Brotli, disable Brotli decoding until a fix ships.