One Brotli Bug, Many Products: CVE-2026-111497 Reaches Node.js, Bun, Python and Envoy
A memory-safety bug in the reference Brotli decompression library has turned into a cross-ecosystem patching exercise. Tracked as CVE-2026-111497, it lets specially crafted Brotli-compressed data write past the end of a buffer. Because the same decoder is embedded in runtimes, proxies and Python libraries, the fix has to land product by product — and some of those products are only now catching up.
What happened
Patched Node.js releases and an updated Brotli library shipped on 21 October 2026, and fixes for other affected software have followed over the days since. The change that closes the hole actually entered the Brotli source tree back in February, but nobody recognised it as a security fix at the time and no Brotli release carried it until October — so downstream projects kept bundling the vulnerable decoder for months.
A malicious payload can corrupt memory and cause a crash, a memory leak or, in the worst case, execution of attacker-controlled code. Remote code execution has been demonstrated on one unpatched build — Node.js 24.22.0 for Linux on ARM64 — delivered both as a fetched response and as an uploaded request body. It took several attempts, the exploit has not been released, and code execution has not been shown on the other affected products. No exploitation in the wild has been reported, and there is no reliable public proof-of-concept.
Severity depends on who is scoring: the CVE carries a critical 9.2 on CVSS 4.0, while some vendors classify it as high or important (around 8.1).
Who is affected
| Software | Vulnerable | Fixed | Exposed when |
|---|---|---|---|
| Node.js | releases before the 21 October security update | 21 October security releases | fetch() reads a br response, or a body parser unpacks a Brotli upload |
| Bun | 1.4.3 and earlier | 1.4.4 | fetch() reads a br response, or code uses node:zlib |
| Envoy | up to 1.39.2, 1.38.5, 1.37.7, 1.36.11 | 1.40.0, 1.39.3, 1.38.6, 1.37.8, 1.36.12 | the Brotli decompressor is configured |
| Istio | 1.31.0–1.31.1, 1.30.0–1.30.5, 1.29.0–1.29.8 | 1.31.2, 1.30.6, 1.29.9 | Brotli decompression is enabled |
Python Brotli | 1.2.0 and earlier | 1.2.1 | installed, and an HTTP client decodes br |
Python brotlicffi | 1.2.0.x and earlier | 1.2.1.0 | installed, and an HTTP client decodes br |
| cdxgen | standalone binaries/images 13.4.0, 12.8.8 and earlier | 13.5.0, 12.8.9 | scanning untrusted input |
Why it matters
The deciding question is simple: does your software decode Brotli data that someone else controls?
- Node.js and Bun are exposed when the built-in
fetch()receives a response sent withContent-Encoding: br, or when request-body middleware — such as Express 5 with body-parser 2 — unpacks a Brotli upload. A bare Node.js HTTP server does not decode request bodies by itself. - Envoy and Istio are only reachable when Brotli decompression is switched on, for example through an Envoy filter. With it off, the bug cannot be triggered.
- Python is the sneaky case. Simply having
Brotliorbrotlicffiinstalled is enough: popular HTTP clients such as requests, urllib3, httpx and aiohttp pick them up automatically and decode Brotli responses on their own. An application can be exposed without ever importing Brotli in its own code.
The flaw also cuts both ways. An unpatched server that accepts compressed input could be taken over by a malicious client, and an unpatched client that accepts compressed responses could be taken over by a malicious server. A web application firewall can filter inbound traffic, but it does nothing for responses your own code fetches from other servers — on that path, only an update closes the gap.
Two blind spots make this harder to track. The CVE record points at the upstream Brotli repository rather than the PyPI packages, so dependency scanners that rely on GitHub's advisory data may not flag the Python libraries yet; dedicated entries (PYSEC-2026-4322 and PYSEC-2026-4323) were only added on 23 October. And operating-system packages are moving at different speeds: Debian 13 (trixie) shipped a fixed brotli (1.1.0-2+deb13u1) on 23 October, while Amazon Linux 2023 still listed its brotli and Node.js 24 packages as pending a fix as of 22 October.
What to do
- Update to a fixed version from the table above, then restart services and rebuild container images — a running process keeps the old decoder in memory until it restarts.
- If you can't update yet, stop decoding untrusted Brotli:
- reject incoming requests with
Content-Encoding: brbefore any proxy or parser decodes the body; - turn off automatic Brotli decoding in HTTP clients and reject Brotli responses before they are decoded;
- in Python, uninstall
Brotliandbrotlicffiso clients fall back to gzip and deflate.
- reject incoming requests with
- Don't rely on
Accept-Encodingalone. Removingbrfrom the header is not a defence on its own — a hostile server can send Brotli regardless of what the client asks for. For Node.js there is no published workaround: updating the runtime is the fix. - Check manually, not just with your scanner. Run
pip show brotli brotlicffiacross Python environments and images, and track your distribution's brotli and Node.js packages until they are patched.
Bugs like this hide in optional, transitive dependencies that nobody chose on purpose. Our AI-assisted code review inventories what your applications actually pull in — including libraries that HTTP clients load silently — and maps them against current advisories, so a vulnerable decoder doesn't stay invisible just because your code never imports it directly.
