Brotli decoder bug in KEV (CVE-2026-111497, Node2Shell): find every copy, patch, and check for exploitation attempts
For when you need to clear CVE-2026-111497 before the Nov 10 KEV deadline. The bug lives wherever a vulnerable Brotli decoder is bundled, not only in Node.js, and first in-the-wild attempts were seen Oct 26 (ELLIO). Most failed attempts crash the process, so crashes are a signal too.
Find exposure
Exposure means something decodes Brotli from a source an attacker can influence.
- Inventory Node.js runtimes below 22.23.4, 24.22.1 and 26.12.1 (including EOL 20.x, 23.x, 25.x, which get no fix); do not trust process.versions.brotli, which reads 1.2.0 either way
- Search SBOMs, images and lockfiles for brotli/libbrotli below 1.0.10, 1.1.1 or 1.2.1, PyPI Brotli/brotlicffi below 1.2.1, Bun below 1.4.4, Envoy/Istio with the Brotli decompressor, .NET apps that turned on Brotli decompression, PHP Windows builds, FFmpeg/libjxl, ClickHouse and Arrow
- Flag paths: inbound Content-Encoding: br bodies (Express 5 / body-parser 2, Koa bodyparser), outbound fetch/axios/got responses from attacker-influenced URLs (link previews, webhooks, agent URL tools), and direct zlib/brotli calls on client data
Patch and rebuild
Upgrading the host does not fix a copy baked into an image or binary.
- Upgrade runtimes and libraries, then rebuild container images, bun build --compile executables, .NET self-contained/NativeAOT apps and CI/build images
- Fix Dockerfiles that pin vulnerable Node.js tags, then redeploy and restart long-running processes
- Until patched, drop or reject inbound requests with Content-Encoding: br at the proxy or WAF where the app does not need them
Hunt
Use ELLIO's Oct 26 indicators and the crash pattern.
- Requests with Content-Encoding: br and very large bodies (the observed exploit body was 23,069,983 bytes, SHA-256 7fcbdaae...c5c4b) and traffic from 94.154.43.7
- User agent "node2shell-check/1.0" (reconnaissance) followed by more Brotli POSTs from other sources
- Bursts of Node.js worker segfaults or restarts, or Python/PHP/Ruby workers hanging at high CPU right after br requests
- After any crash burst, look for new child processes of node (sh, curl, wget), new outbound connections and changed files
Contain and clean up
Crashes can leak secrets even when the exploit fails.
- Restrict and expire core dumps (/var/lib/systemd/coredump); they can hold other users' sessions and tokens
- If a shell may have run, isolate the host or pod, preserve logs, rotate secrets available to that service and rebuild from a clean image
- Record which products were vendor-patched and which you rebuilt yourselves, for the KEV attestation