If you run Node and PHP side by side on one box, the single most useful thing you can do about CVE-2026-111497 (nicknamed “Broccoli2Shell”) is stop trusting the brotli version string. The flaw is an out-of-bounds write in Google’s Brotli C decoder, present in library versions 1.0.3 through 1.2.0 and fixed upstream in 1.0.10, 1.1.1 and 1.2.1. Node shipped the fix inside its own build on 21 October 2026 in v22.23.4, v24.22.1 and v26.12.1, but process.versions.brotli still reports 1.1.0 on a patched Node. Key your audit on the Node version, not that string.
We run WordPress plus our Paperkite plugin and several Laravel apps on a CloudPanel VPS, with Node services for a few side jobs. That mix is exactly the problem here: brotli decoding reaches in through Node’s fetch() and zlib, through the PHP brotli PECL extension, through Python HTTP clients, and through the system shared library that nginx and other C programs link against. So “are we patched?” is really four separate questions. Here is how we answered each one, tested on a Linux container running Node 22.23.4, PHP 8.3.6 and libbrotli 1.1.0 on 27 October 2026.
What we actually run to find brotli

The detection commands we ran on the box, with the real output from this run.
Four checks, four surfaces:
# 1. Node: the bundled decoder. Judge by the Node version, not the brotli string.
node --version # v22.23.4 -> patched line
node -p "process.versions.brotli" # 1.1.0 -> unchanged, ignore it
# 2. System shared library (nginx, CloudPanel, any C consumer)
dpkg -l | grep -i brotli # libbrotli1 1.1.0-2build2
# 3. PHP and Python
php -m | grep -i brotli # no output here: extension not loaded
python3 -c "import brotli" # ModuleNotFoundError: not installed
# 4. What is decoding brotli right now
grep -l brotlidec /proc/*/maps | wc -l # 0 on this box
On our box Node was already on the fixed 22.x line, the PHP brotli extension was not loaded, and Python had no brotli package. That cleared three of the four surfaces. The one that did not clear was the system library.
The system library is the part people miss
libbrotli1 reported 1.1.0-2build2. Upstream 1.1.0 sits inside the affected range, and the fix is in 1.1.1. So the question is whether the distro backported it. We checked the package changelog directly:
zcat /usr/share/doc/libbrotli1/changelog.Debian.gz | head
# newest entry: "No-change rebuild for CVE-2024-3094" (31 Mar 2024)
Nothing about CVE-2026-111497. On this image the shared library is unpatched. That matters for any C program that links brotli: on a CloudPanel box, nginx with the brotli module is the one to watch. The good news from check 4 is that nothing currently has brotlidec mapped, so our live exposure through the shared library is zero until something loads it. We pinned a reminder to re-run the grep -l brotlidec check after the next nginx or CloudPanel update and to apt upgrade libbrotli once the distro publishes a fixed build.
Does patched Node actually reject bad input
Upgrading is the fix, but we wanted to see the patched behaviour, not just trust the version number. The vulnerability came from the decoder treating a malformed block switch as “need more input” and appending attacker bytes to an eight-byte internal buffer. A patched build should instead raise a clean format error. So we fed valid, malformed and truncated brotli to node:zlib:

Patched Node round-trips valid data and rejects malformed and truncated streams with a clean error instead of crashing.
valid round-trip : ideaxecution brotli check
malformed input : rejected -> Z_BUF_ERROR
truncated stream : rejected -> Z_BUF_ERROR
node : v22.23.4 | bundled brotli string: 1.1.0
Two things worth noting. The decoder refuses the bad input cleanly, which is the behaviour we wanted. And the brotli string still reads 1.1.0, which is the trap this whole post is about: that number does not move when Node patches its vendored copy.
The interim block for the surface you cannot patch yet
While the system library waits for a distro update, the cheap mitigation is to refuse brotli-encoded request bodies at the edge, since almost nothing legitimately sends them. On nginx this is a few lines:
# Reject Content-Encoding: br on request bodies (not responses).
map $http_content_encoding $block_br_body {
default 0;
"~*\bbr\b" 1;
}
server {
if ($block_br_body) { return 415; }
}
This only covers inbound bodies your server decodes. It does nothing for brotli your own code fetches from elsewhere, so it is a stopgap, not the fix. The fix is still: upgrade the package, then restart the process or rebuild the image, because installing the update does not swap the decoder inside an already-running process.
The short version
Check Node by version and ignore its brotli string. Check whether the PHP and Python brotli packages are even installed before worrying about them. And do not forget the system libbrotli1, which a distro may not have patched yet: read its changelog, watch what maps brotlidec, and block Content-Encoding: br request bodies at nginx until the fixed library lands.



