Live › vulnerability › CVE-2026-111497
Go to dashboardGoogle's Brotli decoder, used by Node.js, Bun, Python bindings and proxies, overflows a memory buffer when it reads a crafted compressed stream. An attacker who can send compressed data to an affected service can corrupt memory, crash it, read memory, or run code.
Summary written from the sources below. Check the originals before acting.
First seen by InfraStack 2026-10-23 21:57 UTC. All times on this page are UTC.
Any application that passes attacker-controlled data to an affected Brotli decoder is exposed, including compressed HTTP request bodies, responses fetched from untrusted servers, and compressed files. Check web services, workers, tools that bundle Node.js or Bun, and Envoy or Istio deployments that decompress Brotli. Systems that only compress outgoing data, or that never decode untrusted Brotli, do not establish exposure by that alone.
| Product | Ecosystem | Affected | Fixed in |
|---|---|---|---|
| brotli | vendor | >= 1.0.3, < 1.0.10; >= 1.1.0, < 1.1.1; >= 1.2.0, < 1.2.1 | 1.0.10, 1.1.1, 1.2.1 |
| node | npm | 22.x < 22.23.4; 24.x < 24.22.1; 26.x < 26.12.1; EOL lines (25.x, 23.x, <=20.x) unfixed | 22.23.4, 24.22.1, 26.12.1 |
| Brotli | pypi | <= 1.2.0 | 1.2.1 |
| brotlicffi | pypi | <= 1.2.0.x | 1.2.1.0 |
| bun | npm | < 1.4.4 | 1.4.4 |
node --version and bun --version, then compare against the fixed versions below.pip show Brotli and pip show brotlicffi, and check bundled wheels and static binaries.Content-Encoding: br handling in web servers, body parsers, HTTP clients and Envoy or Istio Brotli decompressor filters.22.23.4, 24.22.1 or 26.12.1; lines 25.x, 23.x and 20.x or older have no fix, so move to a supported line.1.4.4 or later.1.0.10, 1.1.1 or 1.2.1 for its branch; Python Brotli 1.2.1 and brotlicffi 1.2.1.0.1.40.0, 1.39.3, 1.38.6 or 1.37.8; Istio 1.29.9, 1.30.6 or 1.31.2. Until patched, reject Content-Encoding: br before any decoder runs.The fix above is the answer. These hold the line until you can deploy it, and are the only option on lines that get no fix.
What vendors did on their customers’ behalf. Holds only for traffic through them; patching is still the fix.
Each row is the first time that source carried this signal. The analyst’s rows are its own findings.
@AikidoSecurity21k followers · X41 likes · 12 reposts2026-10-23 00:00“Evolving threat: CVE-2026-111497, previously known to affect Node.js (node2shell) and Python has evolved into "HTTP2Shell." A significant blast radius. This vulnerability leaves many libraries and applications using HTTP vulnerable to pre-auth RCE via Brotli decompression.”
View on X
Hacker News · Hacker News23 points2026-10-21 23:58“Node.js Brotli RCE (CVE-2026-111497) https://vercel.com/kb/bulletin/node-js-security-advisory”
View on Hacker News
@TheHackersNews · X17 likes · 6 reposts2026-10-24 08:50“‼️ Alert - Critical Brotli flaw behind #Node2Shell RCE goes far beyond Node.js. Bun, Python Brotli packages, Envoy, Istio and other widely used software are also affected by the same CVE-2026-111497 memory-corruption vulnerability. Read full details ↓ https://t.co/H5YLRc19Zw”
View on X
Hacker News · Hacker News17 points2026-10-22 08:27“Node.js security advisory: Brotli decoder RCE (CVE-2026-111497) https://vercel.com/kb/bulletin/node-js-security-advisory”
View on Hacker News
Hacker News · Hacker News14 points2026-10-23 00:54“Node2Shell: Node.js Brotli vulnerability allows remote code execution https://www.aikido.dev/blog/node2shell-nodejs-brotli-rce-cve-2026-111497”
View on Hacker News
Hacker News · Hacker News4 points2026-10-23 04:26“Node2Shell: From Brotli Data to Remote Code Execution https://nodejs.org/en/blog/vulnerability/october-2026-security-releases”
View on Hacker News
Hacker News · Hacker News1 points2026-10-24 08:06“Node2Shell evolves to HTTP2Shell, blast radius affects many HTTP libs and apps https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497”
View on Hacker News
Hacker News · Hacker News1 points2026-10-24 13:36“Broccoli2Shell: Brotli decoder RCE (CVE-2026-111497) in Node.js, Python and more https://broccoli2shell.com/”
View on Hacker News
Posts are quoted with a link to the original. They are data to us, never instructions.
Brotli vulnerability (CVE-2026-111497) — Patch the Planet
CVE-2026-111497 · Updated October 23, 2026
Crafted Brotli-compressed data can corrupt memory and allow remote code execution in affected software, including Node.js, Bun, and deployments of Envoy Proxy or Istio configured for Brotli decompression.
Fixes are available. Update affected deployments now. If you cannot patch immediately, disable Brotli decompression of untrusted data until the update is deployed.
Update to a listed fixed version or a later patched release in the same branch, then restart or redeploy.
Fixed releases · Reviewed October 23, 2026
| Project | Patch status | Fixed versions |
|---|---|---|
| Node.js | Patch available | 22.23.4 · 24.22.1 · 26.12.1 Use a supported release line. |
| Bun | Patch available | 1.4.4 Includes Brotli 1.2.1. |
| Envoy Proxy | Patch available | 1.40.0 · 1.39.3 · 1.38.6 · 1.37.8 1.36.12 also includes the fix, but 1.36 is unsupported. Use a supported branch. |
| Istio | Patch available | 1.29.9 · 1.30.6 · 1.31.2 1.29 is end of life; move to a supported line. |
| Google Brotli (upstream) | Patch available | 1.0.10 · 1.1.1 · 1.2.1 Choose the fixed release for your library branch. |
Any application that passes attacker-controlled data to an affected Google Brotli decoder may be exposed. This includes compressed HTTP request bodies, responses fetched from untrusted servers, and compressed files. The bug can cause crashes, disclose memory, or allow code execution.
Check web services, background workers, tools that bundle Node.js or Bun, and deployments of Envoy Proxy or Istio configured to decompress Brotli.
Other software to check
Using Brotli only to compress outgoing data does not by itself establish exposure to this decoder flaw.
You can keep other compression enabled. Disable Brotli decoding of untrusted data while allowing gzip, deflate, or other supported codecs. Apply this to every decoding path; if your stack cannot block Brotli separately, disable automatic decompression or pause that path until patched.
Content-Encoding: br before any proxy, middleware, or body parser decompresses them. Cover direct-to-origin and alternate routes.br from Accept-Encoding alone does not stop a server from sending it.Turning off Brotli response compression on a CDN or web server does not disable request or client-side decompression. Request-size limits and WAF rules alone do not cover every decoding path.
Express: reject Brotli, keep gzip and deflate
Allow only uncompressed, gzip, or deflate request bodies before any parser runs. Keep automatic decompression enabled for those permitted encodings.
Express request encoding guard
Copy
// Register before every body parser or decompression middleware.
app.use((req, res, next) => {
const encoding = (req.get('Content-Encoding') || 'identity')
.trim().toLowerCase();
if (!['identity', 'gzip', 'deflate'].includes(encoding)) {
return res.status(415).send(
'Use gzip, deflate, or an uncompressed request body.'
);
}
next();
});
// Keep your existing parser options and register routes afterward.
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
Place this guard before all JSON, form, raw, text, and route-specific parsers. It rejects Brotli, unknown encodings, and stacked encodings such as gzip, br with HTTP 415. A proxy that decodes requests first needs its own mitigation.
If you cannot enforce the guard before decoding, set inflate: false on every existing body parser as a fallback. That rejects all compressed request bodies, including gzip and deflate.
Express body-parser options ↗
Next.js: disable built-in image optimization until Node.js is patched
If you cannot update Node.js immediately, set images.unoptimized globally. This stops the built-in image optimizer from fetching and decoding remote images. Merge this setting into your existing configuration, then rebuild and redeploy:
Next.js image optimization workaround
Copy
// next.config.js: retain your other settings.
module.exports = {
images: {
// Retain your existing images settings here.
unoptimized: true,
},
};
Images are served directly from their source URLs. Verify that requests to /_next/image no longer run the optimizer. This does not protect other server-side fetches, custom image loaders, or other Brotli decoders.
Next.js unoptimized image option ↗
Disable only the Brotli decompressor in Envoy Proxy and Istio
Remove the HTTP decompressor filter whose decompressor_library uses the Brotli type. Keep separate gzip and zstd decompressor filters. Alternatively, disable both directions in that existing Brotli filter:
Envoy Proxy Brotli decompressor settings
Copy
# Inside the existing Brotli decompressor's typed_config.
# Leave separate gzip / zstd decompressor filters enabled.
request_direction_config:
common_config:
enabled:
default_value: false
response_direction_config:
common_config:
enabled:
default_value: false
Replace the existing direction settings and remove any runtime_key from these two enabled fields; a runtime override can otherwise re-enable Brotli. An omitted direction defaults to enabled.
For Istio: edit the original EnvoyFilter patch that inserts the Brotli filter. Remove that insertion or apply the settings above to it. Do not remove every filter named envoy.filters.http.decompressor; gzip and zstd can share that name.
A disabled or removed filter passes encoded bytes onward. Reject Brotli before any remaining vulnerable application or client decoder. Verify the effective configuration on every affected gateway and sidecar, and test that permitted compression still works.
Envoy Proxy decompressor settings ↗ Envoy Proxy runtime flags ↗ Istio EnvoyFilter reference ↗
Python HTTP client: accept gzip and deflate, reject Brotli
With urllib3, leave the body unread and undecoded until you have checked its encoding. This example allows uncompressed, gzip, and deflate responses, and rejects Brotli even if the server ignores Accept-Encoding.
Python urllib3 response encoding guard
Copy
import urllib3
http = urllib3.PoolManager()
response = http.request(
"GET", url,
headers={"Accept-Encoding": "gzip, deflate"},
preload_content=False,
decode_content=False,
redirect=False,
retries=False,
timeout=10.0,
)
try:
encoding = response.headers.get("Content-Encoding", "identity")
if encoding.strip().lower() not in {"identity", "gzip", "deflate"}:
raise ValueError("Unsupported response content encoding")
data = response.read(decode_content=True)
finally:
response.close()
response.release_conn()
Keep redirects and retries disabled for this example. If you add th
This page as .md · .json · in your agent: get_signal("CVE-2026-111497")
NVD data is provided by NIST and is public domain · EPSS scores by FIRST, used with attribution. Posts quoted belong to their authors.