---
title: Brotli decoder bug in KEV (CVE-2026-111497, Node2Shell): find every copy, patch, and check for exploitation attempts | ctxsec
url: https://ctxsec.com/playbooks/brotli-node2shell-kev-exposure-response
---

[← Playbooks](/playbooks)

# 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.

For: AppSec / platform, SOC, Container / DevOps, IR lead

[1. Find exposure](#s1)[2. Patch and rebuild](#s2)[3. Hunt](#s3)[4. Contain and clean up](#s4)

1.

Step 1 of 4

__

### 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

2.

Step 2 of 4

__

### 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

3.

Step 3 of 4

__

### 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

4.

Step 4 of 4

__

### 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

Original content by ctxsec. Printable checklist: use your browser's print view.
