Back to Intelligence

CVE-2026-111497: Brotli Decoder Memory Corruption in Node.js, Bun, Python and Envoy — Detection and Remediation Guide

SA
Security Arsenal Team
October 24, 2026
12 min read

A memory-corruption vulnerability in Google's Brotli decompression library — tracked as CVE-2026-111497 — is the root cause behind the recently disclosed critical code-execution flaw in Node.js, and the blast radius is significantly wider than a single runtime. Because Brotli is embedded, statically linked, or vendored into an enormous number of downstream projects, the same defective decoder code now sits inside Bun, the Python Brotli and brotlicffi packages, and Envoy proxies configured to decompress Brotli-encoded traffic.

This is a classic supply-chain scenario: one flaw in a ubiquitous upstream compression library propagates silently into runtimes, proxies, and application stacks that most asset inventories never track at the library level. Any service that accepts and decompresses Brotli-compressed input from an untrusted source — an HTTP request body, an API payload, a proxied response — is a potential target. Crafted compressed data can trigger a write past the end of an allocated buffer, corrupt process memory, and, per the reporting on the Node.js impact, be leveraged for code execution.

Defenders need to treat this as an urgent inventory-and-patch exercise, not a routine update cycle. If you run Node.js or Bun applications that ingest user-controlled compressed data, Python services using brotli/brotlicffi, or Envoy with Brotli decompression enabled at the edge, you are in scope.

Technical Analysis

Affected Products

Based on the current disclosure, confirmed affected components include:

  • Node.js — the critical code-execution flaw that brought this issue to light; Brotli support is built into the runtime (zlib module with Brotli support), so any Node application decompressing untrusted Brotli data is exposed.
  • Bun — the alternative JavaScript runtime ships with Brotli decompression and inherits the same vulnerable decoder code.
  • Python Brotli and brotlicffi packages — the two dominant PyPI bindings for Google's Brotli library, used extensively in web scraping, HTTP clients (urllib3, requests when Brotli content-encoding is negotiated), and data pipelines.
  • Envoy proxy — when configured with Brotli decompression (decompressor filter or compression libraries), Envoy will unpack attacker-influenceable compressed payloads in the proxy's own process context, which is a particularly dangerous place for memory corruption given Envoy's position at the trust boundary.

Because Brotli is frequently vendored or statically compiled into these projects, the vulnerable code may not appear as a discrete system package. Do not rely solely on dpkg/rpm output to determine exposure — you must check the runtime and package versions themselves and, where possible, the Brotli version they link against.

Vulnerability Mechanics

CVE-2026-111497 is a memory-corruption flaw in the Brotli decoder: a crafted compressed stream causes the decoder to write past the end of an output buffer (an out-of-bounds write / heap overflow condition). From a defender's perspective, the relevant characteristics are:

  • Attack vector is data, not credentials. The attacker only needs to get a malicious Brotli payload to a decompression path. No authentication, no user interaction — just reachability of a service that will decompress the input.
  • Delivery channels are plentiful. HTTP request/response bodies with Content-Encoding: br, API uploads, message-queue payloads, proxied traffic through Envoy, and any application code that calls brotli.decompress() (Python), zlib.brotliDecompress*() (Node.js), or the Bun equivalent on externally influenced data.
  • Impact scales with the host process. In Node.js/Bun, corruption occurs in the application process — yielding code execution as the service account. In Envoy, it occurs in the proxy handling your north-south traffic. In Python workers, it hits whatever pipeline process performs decompression.

The Node.js project characterized the downstream impact as a critical code execution flaw, which is consistent with heap corruption in a network-reachable decompression path. At the time of writing, the CVSS score and the complete list of fixed version numbers for every downstream project were still being published via vendor advisories; there is no confirmed in-the-wild exploitation reported yet, but the flaw is now public, the affected component list is explicit, and working back from a patched diff to a crashing (then weaponizable) input is a well-understood exercise for motivated researchers. Expect proof-of-concept material to follow quickly. Check CISA KEV and the vendor advisories below daily until you are patched.

Detection & Response

Library-level memory corruption is notoriously hard to detect at the point of exploitation — the malicious input looks like ordinary compressed traffic. The highest-fidelity detective strategy is therefore twofold: (1) detect the aftermath — a decompression-hosting process crashing or, worse, spawning child processes it never should — and (2) build an accurate exposure inventory so your patch program targets the right assets. The detections below are tuned for low noise: Node.js, Bun, and Envoy have well-defined legitimate child-process behavior, and deviations are strongly suspicious.

Sigma Rules

YAML
---
title: Node.js or Bun Runtime Spawning Shell or Script Interpreter
id: 3f8a1b72-6c4d-4e91-b2a7-9d1e5f3c8a21
status: experimental
description: Detects Node.js or Bun processes spawning command shells or script interpreters, consistent with post-exploitation behavior following memory corruption in the Brotli decoder (CVE-2026-111497). Node and Bun services almost never spawn interactive shells in production.
references:
  - https://thehackernews.com/2026/10/brotli-decoder-flaw-behind-nodejs-rce.html
author: Security Arsenal
date: 2026/10/27
tags:
  - attack.execution
  - attack.t1059
  - attack.t1203
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\node.exe'
      - '\bun.exe'
  selection_child:
    Image|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\wscript.exe'
      - '\cscript.exe'
      - '\mshta.exe'
      - '\rundll32.exe'
      - '\certutil.exe'
      - '\bitsadmin.exe'
      - '\curl.exe'
  condition: selection_parent and selection_child
falsepositives:
  - Build tooling and CI/CD agents invoking Node-based task runners (npm scripts calling shell commands)
  - Legitimate installer/bootstrap scripts executed via node
level: high
---
title: Linux Runtime or Proxy Process Spawning Shell (Node Bun Python Envoy)
id: 8c2e4d16-3a7f-4b58-9e1c-6b4a2f8d5e93
status: experimental
description: Detects node, bun, python, or envoy processes spawning shells or network utilities on Linux, consistent with code execution following Brotli decoder memory corruption (CVE-2026-111497). Envoy in particular should never spawn child processes.
references:
  - https://thehackernews.com/2026/10/brotli-decoder-flaw-behind-nodejs-rce.html
author: Security Arsenal
date: 2026/10/27
tags:
  - attack.execution
  - attack.t1059.004
  - attack.t1203
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|endswith:
      - '/node'
      - '/bun'
      - '/envoy'
      - '/python'
      - '/python3'
  selection_child:
    Image|endswith:
      - '/sh'
      - '/bash'
      - '/dash'
      - '/zsh'
      - '/curl'
      - '/wget'
      - '/nc'
      - '/ncat'
      - '/socat'
      - '/python'
      - '/python3'
      - '/perl'
      - '/base64'
  condition: selection_parent and selection_child
falsepositives:
  - Python applications legitimately shelling out via subprocess (common in automation frameworks)
  - npm lifecycle scripts (postinstall) executing shell commands during builds
  - Envoy hot-restart wrappers (rare; typically exec, not spawn)
level: high
---
title: Crash Artifact for Brotli-Decompressing Process
id: 1d7f3a95-2b8c-4e64-a5d9-7c3e1b6f4a28
status: experimental
description: Detects Windows Error Reporting capturing a crash of node.exe, bun.exe, or python.exe, which may indicate attempted exploitation of the Brotli decoder heap corruption (CVE-2026-111497). Repeated crashes of a network-facing runtime warrant immediate triage.
references:
  - https://thehackernews.com/2026/10/brotli-decoder-flaw-behind-nodejs-rce.html
author: Security Arsenal
date: 2026/10/27
tags:
  - attack.exploitation_for_client_execution
  - attack.t1203
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith:
      - '\WerFault.exe'
      - '\wermgr.exe'
    CommandLine|contains:
      - 'node.exe'
      - 'bun.exe'
      - 'python.exe'
  condition: selection
falsepositives:
  - Application bugs and legitimate crashes in development environments
  - Resource exhaustion (OOM) terminations
level: medium

KQL (Microsoft Sentinel / Defender)

The following hunt covers both post-exploitation process behavior on endpoints and crash telemetry from Linux hosts ingested via Syslog/CEF — important because most Node.js, Bun, and Envoy deployments run on Linux and are hunted in Sentinel through log forwarding rather than MDE.

KQL — Microsoft Sentinel / Defender
// Hunt 1: Post-exploitation child processes of Brotli-decompressing runtimes (Windows/Linux via MDE)
let SuspectParents = dynamic(["node", "node.exe", "bun", "bun.exe", "envoy", "python", "python3", "python.exe"]);
let SuspectChildren = dynamic(["cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe", "rundll32.exe", "certutil.exe", "bitsadmin.exe", "curl", "curl.exe", "wget", "sh", "bash", "dash", "nc", "ncat", "socat", "base64", "perl"]);
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName in~ (SuspectParents)
| where FileName in~ (SuspectChildren)
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, ReportId
| order by TimeGenerated desc;

// Hunt 2: Linux crash/segfault telemetry for affected runtimes via Syslog ingestion
Syslog
| where TimeGenerated > ago(14d)
| where SyslogMessage has_any ("segfault", "general protection fault", "core dumped")
| where SyslogMessage has_any ("node", "bun", "envoy", "python")
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc;

// Hunt 3: Exposure inventory — devices observed running node, bun, or envoy in the last 30 days
let SuspectParents = dynamic(["node", "node.exe", "bun", "bun.exe", "envoy"]);
DeviceProcessEvents
| where TimeGenerated > ago(30d)
| where FileName in~ (SuspectParents)
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), SampleCommandLine = take_any(ProcessCommandLine) by DeviceName, FileName, FolderPath
| order by DeviceName asc;

Velociraptor VQL

Use this artifact to sweep your Linux estate for running instances of the affected runtimes and to locate Brotli library artifacts on disk — the combination gives you both the live exposure and the on-disk linkage evidence you need for remediation tracking.

VQL — Velociraptor
-- CVE-2026-111497 exposure hunt: running Node/Bun/Envoy/Python processes plus Brotli library artifacts on disk
LET processes = SELECT Pid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ '^(node|bun|envoy|python3?)($|\.)'
   OR Exe =~ '/(node|bun|envoy)$'

LET brotli_libs = SELECT FullPath, Size, Mtime
FROM glob(globs=[
  '/usr/lib/**/libbrotli*',
  '/usr/local/lib/**/libbrotli*',
  '/usr/lib/python3*/site-packages/brotli*',
  '/usr/local/lib/python3*/site-packages/brotli*',
  '/usr/local/lib/python3*/site-packages/brotlicffi*',
  '/opt/**/libbrotli*',
  '/**/node_modules/**/brotli*'
])

SELECT 'running_process' AS ArtifactType, Pid, Name, Exe, CommandLine, Username, CreateTime, NULL AS FullPath, NULL AS Size, NULL AS Mtime FROM processes
UNION ALL
SELECT 'brotli_artifact' AS ArtifactType, NULL AS Pid, NULL AS Name, NULL AS Exe, NULL AS CommandLine, NULL AS Username, NULL AS CreateTime, FullPath, Size, Mtime FROM brotli_libs

Exposure Verification and Hardening Script

Run this on Linux hosts (and adapt paths for containers) to enumerate your exposure to CVE-2026-111497, identify which runtimes link Brotli, and apply the temporary Envoy workaround. It is intentionally read-only except for the clearly marked Envoy configuration section.

Bash / Shell
#!/bin/bash
# CVE-2026-111497 Brotli decoder exposure check — Security Arsenal
echo "=== [1] Runtime versions ==="
command -v node  >/dev/null && echo "node:  $(node --version)  ($(command -v node))"
command -v bun   >/dev/null && echo "bun:   $(bun --version)  ($(command -v bun))"
command -v envoy >/dev/null && echo "envoy: $(envoy --version 2>/dev/null | head -1)"

echo "=== [2] Python Brotli packages (all detected pip environments) ==="
for py in $(command -v python3 python 2>/dev/null | sort -u); do
  echo "-- interpreter: $py"
  $py -m pip show brotli brotlicffi 2>/dev/null | grep -E '^(Name|Version|Location)' || echo "   brotli/brotlicffi not installed"
  $py -c 'import brotli, sys; print("   brotli import OK:", getattr(brotli, "__version__", "version unknown"))' 2>/dev/null
done

echo "=== [3] Brotli linkage of running services ==="
for pid in $(pgrep -x node; pgrep -x bun; pgrep -x envoy); do
  echo "-- PID $pid ($(readlink /proc/$pid/exe 2>/dev/null))"
  grep -i brotli /proc/$pid/maps 2>/dev/null | awk '{print $6}' | sort -u | sed 's/^/   maps: /'
done
ldconfig -p 2>/dev/null | grep -i brotli | sed 's/^/   system lib: /'

echo "=== [4] Envoy Brotli decompression configuration ==="
for cfg in /etc/envoy/envoy.yaml /etc/envoy/*.yaml /etc/istio/**/*.yaml; do
  [ -f "$cfg" ] || continue
  if grep -qiE 'brotli' "$cfg"; then
    echo "!! Brotli reference found in $cfg:"
    grep -niE 'brotli|decompressor|content-encoding' "$cfg" | sed 's/^/   /'
  fi
done

echo "=== [5] Node/Bun apps that accept compressed input (heuristic) ==="
grep -rslE 'brotliDecompress|createBrotliDecompress|brotli\.decompress' \
  /srv /opt /home --include='*.js' --include='*.ts' --include='*.py' 2>/dev/null | head -50

echo ""
echo "ACTION ITEMS:"
echo " - Patch Node.js/Bun to the fixed releases per nodejs.org and bun.sh security advisories."
echo " - Upgrade Python packages: pip install --upgrade brotli brotlicffi (verify against the fixed versions on PyPI/GitHub google/brotli)."
echo " - WORKAROUND until patched: remove/disable the Brotli decompressor filter in Envoy and strip 'br' from Accept-Encoding handling at your edge."
echo " - Re-run this script after patching and capture output as remediation evidence."

Remediation

  1. Patch the runtimes first, at the edge first. Prioritize internet-facing and DMZ systems. Apply the fixed Node.js release per the Node.js security advisories (nodejs.org/en/blog/vulnerability and the OpenJS security feed), the fixed Bun release per bun.sh/oven.sh release notes, and updated Envoy builds per envoyproxy.io security advisories. Because fixed version numbers for every downstream were still being published at disclosure time, pull the exact target versions from those advisories rather than secondary reporting — and verify the Brotli component version inside each patched artifact (the real fix lands in the upstream google/brotli release; downstreams consume it).
  2. Upgrade Python dependencies everywhere, including containers and virtualenvs. Run pip install --upgrade brotli brotlicffi in every environment, then rebuild and redeploy container images — a patched base image does nothing for images already deployed with a pinned, vulnerable wheel. Audit requirements.txt and lockfiles for hard pins to vulnerable versions.
  3. Apply the workaround where patching lags. In Envoy, disable the Brotli decompressor filter and stop advertising/accepting br content-encoding for untrusted traffic paths. In application code, gate Brotli decompression behind source trust: if you cannot patch a service quickly, reject Content-Encoding: br from unauthenticated clients at your WAF or reverse proxy.
  4. Rebuild your SBOM-driven inventory. This CVE is the textbook case for software composition analysis: the vulnerable code travels inside the runtime, not as a visible system package. Ensure your SCA tooling flags brotli as a transitive component of Node.js, Bun, Envoy, and Python wheels, and add CVE-2026-111497 to your vulnerability scanner's priority checks. Watch CISA KEV — given the prevalence of Brotli, KEV addition would carry a federal remediation deadline and should trigger your emergency patch SLA regardless of your sector.
  5. Hunt retroactively. The flaw is newly public, but the vulnerable code has been in place for some time. Run the Sigma/KQL/VQL content above across at least 14–30 days of retained telemetry. Any crash clustering on a Brotli-decompressing service — especially repeated segfaults of the same node/bun/envoy PID family followed by restarts — deserves full DFIR triage, not a ticket queue.
  6. Validate with your own compressed-input regression tests. After patching, send malformed and boundary-condition Brotli streams (fuzzing corpora are appropriate here) against staging instances to confirm services handle them without crashes before you close the remediation ticket.

This vulnerability is a reminder that decompression libraries are among the highest-value targets in the modern stack: they sit directly on the untrusted-data path, execute with the privileges of critical services, and are almost never inventoried. Treat CVE-2026-111497 as both a patch event and a forcing function to close that inventory gap permanently.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.