psf-brotli-oct2026-check(8)

Script: /opt/psf-security-patches/brotli/brotli-oct2026-check.sh. Tool page: Brotli. Source. With the package installed: man psf-brotli-oct2026-check.

Brotli decoder out-of-bounds write, October 2026: read-only checker  (v1)
CVE-2026-111497

If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation

Known as Broccoli2Shell (first called Node2Shell). Google's Brotli decoder
(libbrotli / libbrotlidec, 1.0.3 through 1.2.0) can be handed a block switch
that cannot happen. DecodeBlockTypeAndLength() returned a plain boolean, so
the caller could not tell a malformed stream from one that needed more input,
and the fast path ignored the result. The decoder kept appending attacker
bytes to an eight-byte internal buffer, writing past its end: a crash, a
memory disclosure, or remote code execution (CWE-252 and CWE-787). The flaw
is in the upstream C library, and the same CVE has advisories across
everything that bundles it: Node.js, Bun, Envoy, Istio, the Python brotli and
brotlicffi bindings, the Ruby and PHP extensions, and OS packages. Some
people are calling the broadened picture "HTTP2Shell", since any HTTP path
that decodes untrusted Brotli can be a route to it.

Fixed upstream in Brotli 1.0.10, 1.1.1 and 1.2.1 (the decoder now returns
BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH, -17). Distributions backport the
fix into their own libbrotli builds, sometimes under an older version number.
A copy older than 1.0.3 is outside the advisory's affected range, but this
script still reports it as not fixed: it is unsupported, so it moves to 1.0.10,
1.1.1 or 1.2.1.

This is read-only: it finds what needs updating and judges each against the
fixes. It does NOT change anything. The fix is to update the library or the
runtime. There is no host-wide switch to turn Brotli off; disabling Brotli
decoding is application-specific (reject
Content-Encoding: br before it is decompressed, turn off automatic Brotli in
HTTP clients, disable the Brotli decompressor filter in Envoy/Istio). See
the repository README and https://patchtheplanet.org/brotli

For the Node.js guard (loading a require-hook that refuses to decode),
use node/node-oct2026-mitigate.sh and node/brotli-guard.cjs instead. This
script only reports Node's version.

Usage:
  ./brotli-oct2026-check.sh [command]

  check (default)  every libbrotli on the host, the running processes that
                   have libbrotlidec loaded (and any still running a library
                   that was replaced on disk), the runtimes that bundle their
                   own Brotli (Node.js, Bun, Python's brotli and brotlicffi,
                   the Ruby brotli gem, the PHP brotli extension, Envoy,
                   Istio, cdxgen), and libbrotli inside running containers,
                   with whether each carries the fix. It also lists other
                   software on PATH that bundles an unfixed copy (.NET,
                   DuckDB, ClickHouse); that list is informational. Root
                   optional. Exit 0 = nothing exposed, 1 = a vulnerable
                   Brotli is present, 2 = something couldn't be read.
  hunt             read-only: the journal and logs for process crashes that
                   look like a Brotli decoder overflow (segfaults with
                   brotli/BrotliDecoder frames, heap corruption aborts).
                   Exit 0 = clean, 1 = findings.
  version          print the script version.

Env overrides:
  FIXED_BUILDS="1.0.9-2+deb12u2 1.1.0-2ubuntu0.1"
                                    extra distro libbrotli builds known to
                                    carry the fix, space-separated full
                                    versions. Checked alongside a built-in
                                    list of known builds (Debian 13's
                                    1.1.0-2+deb13u1), which a value here does
                                    not replace.
  BRANCH_FIXED="1.0:1.0.10 1.1:1.1.1 1.2:1.2.1"
                                    first fixed upstream release per branch
  RUBY_BROTLI_FIXED="0.9.1"         first fixed Ruby brotli gem
  PHP_BROTLI_FIXED="0.21.1"         first fixed PHP brotli extension
  SCAN_CONTAINERS=1                 1 = read libbrotli inside running
                                    containers (default 1; 0 to skip)
  HUNT_SINCE="2026-10-01"           how far back hunt reads the journal
  HUNT_LOGS="/srv/app/log/*.log"    extra log globs for hunt
  NODE_FIXED="22.23.4 24.22.1 26.12.1"
                                    first fixed Node.js release per line
  BUN_FIXED=1.4.4                   first fixed Bun release
  PYBROTLICFFI_FIXED=1.2.1.0        first fixed pybrotlicffi release
  ENVOY_FIXED="1.40.0 1.39.3 1.38.6 1.37.8 1.36.12"
                                    first fixed Envoy release per line
  ISTIO_FIXED="1.29.9 1.30.6 1.31.2"  first fixed Istio release per line
  CDXGEN_FIXED="13.5.0 12.8.9"       first fixed cdxgen release per line

The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.

The PrivacySafe Ecosystem

Shop at Ivy Cyber

Ivy Cyber offers PrivacySafe products and services in the USA and has partnerships with 3NSoft in Canada and Kuip Limited in the European Union. Enterprise services and consulting are available at ivycyber.com

PrivacySafe Foundation is a 501(c)(3) nonprofit public charity that supports the development of the PrivacySafe applications, along with the components they rely upon: 3NWeb protocols, filesystem, documentation, and reference implementations.

PrivacySafe Foundation

Donations to PrivacySafe Foundation support education, research, documentation, and public code. Purchases from Ivy Cyber support PrivacySafe products, services, hosting, and technical support. Together, we're building a better web.