Skip to main content
CVE-2026-111497 "Broccoli2Shell": One Brotli Bug in Node.js, Envoy and Istio. Patch Node First

CVE-2026-111497 "Broccoli2Shell": One Brotli Bug in Node.js, Envoy and Istio. Patch Node First

KU
· Founder & Chief Editor
• 8 min read•5 views

An out-of-bounds write in Google's Brotli decoder, now on CISA's KEV list, reaches Node.js through zlib and Envoy and Istio through the Brotli decompressor filter. Fixed versions, cluster-wide checks and what to block until you patch.

Key takeaways

  • CVE-2026-111497, nicknamed Broccoli2Shell, is an out-of-bounds write in Google's Brotli decoder, scored CVSS 9.2 and added to CISA's KEV catalog on October 27, 2026.
  • Node.js is exposed wherever it decompresses untrusted Brotli; Envoy and Istio only when a Brotli decompressor is configured.
  • Patch Node to 22.23.4, 24.22.1 or 26.12.1 and Istio to 1.31.2, 1.30.6 or 1.29.9.

Upgrade Node.js to 22.23.4, 24.22.1 or 26.12.1 and rebuild every image that bundles it, internet-facing services first. CVE-2026-111497 is an out-of-bounds write in Google's Brotli decoder that can lead to remote code execution, and CISA lists it as exploited. Envoy and Istio need patching too, but only proxies with a Brotli decompressor configured are exposed.

Verified against

Node.js 22.23.4, 24.22.1 and 26.12.1, Envoy 1.36.12 to 1.40.0 and Istio 1.29.9, 1.30.6 and 1.31.2, against the Node.js October 2026 security releases, Envoy GHSA-3wvj-j6qm-62mr, ISTIO-SECURITY-2026-007, Cyber Centre alert AL26-027, the Brotli v1.2.1 release notes and the CISA KEV catalog feed. Checked November 2026.

What happened, in dates

The flaw sits in the streaming Brotli decoder. Per the Node.js advisory, an invalid block switch was treated as a temporary shortage of input instead of a hard format error, so the decoder kept appending attacker-supplied bytes to an eight-byte internal buffer and wrote past its end. That gives an attacker who controls compressed input a crash, a memory leak or, in the worst case, code execution. Brotli 1.0.3 and later are affected; the fixes are 1.0.10, 1.1.1 and 1.2.1.

  • October 15, 2026: Istio publishes ISTIO-SECURITY-2026-007, bundling the Envoy fix with four other Envoy and Istio issues. The same day, Istio 1.29 reaches end of life, so 1.29.9 is its last release.
  • October 21: Brotli v1.2.1 ships with the fix, and Node.js publishes security releases for the 22, 24 and 26 lines, rating the Brotli issue High.
  • October 23: Envoy publishes GHSA-3wvj-j6qm-62mr, scored CVSS 4.0 9.2 (AV:N/AC:L/AT:P/PR:N). Its impact line is blunt: the bug "allows a remote unauthenticated attacker to corrupt adjacent decoder state memory".
  • October 25: Wiz's write-up uses the Broccoli2Shell name and reports that researchers have demonstrated exploitation against unpatched Node.js.
  • October 27: CISA adds CVE-2026-111497 to the Known Exploited Vulnerabilities catalog, with a federal remediation due date of November 10, 2026.
  • October 28: Canada's Cyber Centre issues alert AL26-027 and widens the list: .NET, PowerShell, Bun and the Python brotli and brotlicffi packages also carry the decoder.

Why one library is three different problems

Node.js compiles Brotli into node:zlib. Any code path that decompresses Brotli data you did not produce is in scope: a body parser that inflates Content-Encoding: br requests, a webhook consumer, and HTTP clients that decode responses for you, including the built-in fetch. The last case is the one people miss. A Node service that calls a third-party API or scrapes a page decompresses whatever comes back, and no WAF in front of your ingress ever sees that traffic.

Envoy is only affected when the Brotli decompressor filter is in the HTTP filter chain. Envoy's advisory scopes the impact to deployments that have that decompressor configured. It is a filter you add, not something a stock listener runs.

Istio inherits the Envoy bug in sidecars, gateways and waypoints, but again only where Brotli decompression has been switched on, which Istio's advisory gives an EnvoyFilter as the example of. Most meshes have never done that. The same Istio release also fixes an HTTP/2 AuthorizationPolicy method bypass (CVSS 7.4), which is a reason to upgrade even with no Brotli in sight.

Am I affected? Checks for the whole cluster

Bash
# 1. Which Node, Envoy and Istio proxy images are running?
kubectl get pods -A -o jsonpath='{range .items[*]}{range .spec.initContainers[*]}{.image}{"\n"}{end}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' \
  | grep -Ei 'envoy|proxyv2|node' | sort -u

# 2. Actual Node runtime inside a pod (image tags lie; trust process.version)
kubectl exec -n <ns> <pod> -- node -p 'process.version'

# 3. Has anyone switched on Brotli decompression in the mesh?
kubectl get envoyfilter -A -o yaml | grep -i brotli

# 4. Confirm from the live proxy config, not the CRDs (the filter type is
#    envoy.extensions.compression.brotli.decompressor.v3.Brotli)
kubectl exec -n <ns> <pod> -c istio-proxy -- pilot-agent request GET config_dump \
  | grep -c 'brotli.decompressor'

# 5. Control plane and per-proxy Istio versions
istioctl version
istioctl proxy-status

A 0 from check 4 on your gateways and a representative set of sidecars means Brotli decompression is off in the mesh. Check 2 matters because a node:22 base image pulled in September stays vulnerable however recently you rebuilt the app layer on top of it.

The patch matrix, as of November 8, 2026

ComponentFixed versionsAdvisoryNotes
Brotli (libbrotli)1.0.10, 1.1.1, 1.2.1Brotli v1.2.1 release, AL26-0271.0.3 and later affected
Node.js22.23.4, 24.22.1, 26.12.1October 2026 security releases (Oct 21)End-of-life lines get no fix
Envoy1.40.0, 1.39.3, 1.38.6, 1.37.8, 1.36.12GHSA-3wvj-j6qm-62mr (Oct 23)Affected from 1.18.0; only with the Brotli decompressor
Istio1.31.2, 1.30.6, 1.29.9ISTIO-SECURITY-2026-007 (Oct 15)1.29.9 is the final 1.29 release

For Node, the fix is a runtime upgrade, so the work is in your base images: bump the FROM line or the pinned version in your build image, rebuild, and redeploy every service, not just the ones whose code changed. For Istio, a normal control-plane upgrade followed by a rolling restart of workloads picks up the new proxy; our Istio getting-started guide covers the revision-based flow.

What to block until you patch

Remove Brotli decompressor filters. If check 3 or 4 found one, delete that EnvoyFilter or drop the filter from your Envoy config until the proxies run a fixed release. Compressed bodies then pass through to the application untouched, so this protects the proxy, not a vulnerable Node service behind it.

Reject inbound Brotli bodies at the mesh edge. For Node services behind Istio, a DENY policy on the request header stops br-encoded bodies before they reach the app:

deny-brotli-bodies.yaml
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: deny-brotli-request-bodies
  namespace: istio-system
spec:
  action: DENY
  rules:
  - when:
    - key: request.headers[content-encoding]
      values: ["*br", "br*"]

Applied in the root namespace, it covers the mesh. Istio header matching supports only prefix and suffix wildcards, so a value with br in the middle of a list slips through; most clients send a single encoding.

Where this breaks

The edge block only covers requests coming in. It does nothing for responses your Node services fetch, which is exactly the path a WAF cannot see, and a malicious server can send Brotli even if you never asked for it. Patching is the only fix for that direction. Judge Node by process.version against the matrix, not by the bundled library version in process.versions.brotli. Finally, Brotli is vendored in more places than Node and Envoy: Bun, .NET, PowerShell and the Python packages each need their own upgrade, and a dependency scan of your images is how you find the copies nobody remembers adding.

Questions people ask

Is Istio affected by CVE-2026-111497 by default?

No. Envoy is only exposed when a Brotli decompressor filter is configured, and Istio's advisory treats it as opt-in, for example through an EnvoyFilter, which a default install does not create. Run kubectl get envoyfilter -A -o yaml | grep -i brotli to confirm. Upgrade to 1.31.2, 1.30.6 or 1.29.9 anyway, because the same release fixes an HTTP/2 AuthorizationPolicy bypass that hits any mesh using DENY rules with methods.

Which Node.js versions fix Broccoli2Shell?

Node.js 22.23.4, 24.22.1 and 26.12.1, released October 21, 2026. End-of-life release lines are not patched, and the Node.js project says they should be treated as affected. Check the running version inside the container with node -p 'process.version', because a rebuilt application image can still sit on an old base image. Upgrade the base image, then redeploy every service built on it.

Does blocking Content-Encoding br at the WAF protect Node.js?

Only for incoming request bodies. Node also decompresses Brotli in responses it fetches from other servers, through HTTP clients that decode automatically, and that traffic never passes your ingress WAF. A compromised or malicious upstream API is enough. Treat the edge block as cover for a few days while you roll patched images, not as a fix.

The decision, concretely

  • Node services that call external APIs or accept compressed uploads? Patch today. They are the exposed path and the one no edge control fully covers.
  • Istio mesh with no Brotli EnvoyFilter? Schedule the upgrade this week for the AuthorizationPolicy fix; the Brotli bug cannot be reached.
  • Envoy or Istio with a Brotli decompressor configured? Remove the filter now, then upgrade.
  • Still on an end-of-life Node line or an Istio release older than 1.29? No fix is coming. Move to a supported line.

The call we'd make

Rebuild every Node.js image on 22.23.4, 24.22.1 or 26.12.1 before CISA's November 10 date, starting with services that fetch from the internet, and push the Istio upgrade through in the same window even if your mesh never decodes Brotli. The caveat: this is a library bug, so the Node and Envoy patches do not cover the other runtimes that carry Brotli. Treat it the way we treated the MPTCP kernel CVE: inventory first, then patch by exposure.

Sources

Explore topics:SecurityNewsDevOps
React
Share this post
Cite this article
Plain text

Kiril Urbonas (2026). CVE-2026-111497 "Broccoli2Shell": One Brotli Bug in Node.js, Envoy and Istio. Patch Node First. DevOpsNess. https://www.devopsness.com/blog/brotli-cve-2026-111497-broccoli2shell-node-envoy-istio

Markdown

[CVE-2026-111497 "Broccoli2Shell": One Brotli Bug in Node.js, Envoy and Istio. Patch Node First](https://www.devopsness.com/blog/brotli-cve-2026-111497-broccoli2shell-node-envoy-istio) (Kiril Urbonas, DevOpsNess, 2026-11-08)

KU

Kiril Urbonas

Founder & Chief Editor

590 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.