
Checkmk extension that audits Linux hosts for Brotli decoders (libbrotlidec, Node.js, Python, .NET) affected by CVE-2026-111497, checking versions, backports and stale processes.
A Checkmk extension that shows, for every Brotli decoder on a Linux host, whether it is affected by Broccoli2Shell - CVE-2026-111497, an out-of-bounds write in Google's C Brotli decoder that can lead to remote code execution when a program decompresses Brotli data from an untrusted source (an HTTP response, a request body, an archive). It was disclosed on 2026-10-21/22 and fixed in Brotli 1.0.10, 1.1.1 and 1.2.1, Node.js 22.23.4, 24.22.1 and 26.12.1, the Python packages Brotli 1.2.1 and brotlicffi 1.2.1.0, and .NET 8.0.33, 9.0.22 and 10.0.14.
It ships a small POSIX shell agent plug-in that only collects facts (the system library
libbrotlidec, Node.js binaries, Python Brotli and brotlicffi installations, .NET
runtimes, their versions, package changelogs, what they are linked against, which processes
have them loaded and which still run a replaced one). Whether that means "fixed" or
"vulnerable" is decided by the check plug-in on the Checkmk server, so new
information - another fixed release - only needs an updated .mkp, not a new script on
every host.
Why not just compare version numbers: distributions backport the fix without changing
the upstream version, and they build Node.js against the system library instead of the
copy Node.js bundles. Debian 12 ships libbrotli 1.0.9 and Node.js 18.20.4 (end of
life upstream, no fix) - both fixed, because the updated libbrotli1 package is the decoder
that Node.js runs. The extension therefore reads the changelog of the package that owns
each decoder, and follows Node.js and Python extensions to the library they are linked
against.
cmk_addons.plugins plugin API)./proc/<pid>/maps of all processes). Plain POSIX sh with GNU or busybox
tools; package changelogs are read with dpkg, rpm or apk. Tested on the Debian
family, the Red Hat family, Amazon Linux and Alpine, see below.| Checkmk image | Date | Result |
|---|---|---|
checkmk/check-mk-ultimate:2.5.0p17 | 2026-10-28 | OK (build, cmk-validate-plugins, smoke test, install + discovery + check + agent bake) |
checkmk/check-mk-ultimate:3.0.0-2026.10.28 (daily) | 2026-10-28 | OK (build, cmk-validate-plugins, smoke test, install + discovery + check + agent bake) |
The agent plug-in was run against the distributions' own packages and the official images
on 2026-10-28 (scripts/test_agent_plugin.sh), with a node and a python process that had
the decoder loaded. Afterwards the library, the node binary and the Python extension
modules were replaced on disk, and the restart detection reported the running processes.
Distributions
| Distribution | Decoders | Plug-in result |
|---|---|---|
| Debian 12 | libbrotli 1.0.9-2+deb12u1, Node.js 18.20.4 (linked), python3-brotli | fixed by backport (changelog), Node.js through the library |
| Debian 13 | libbrotli 1.1.0-2+deb13u1, Node.js 20.19.2 (linked), python3-brotli, python3-brotlicffi (linked) | fixed by backport, Node.js and brotlicffi through the library |
| Ubuntu 24.04 | libbrotli 1.1.0-2ubuntu0.1, Node.js 18.19.1 (linked), python3-brotli, dotnet-runtime-8.0 8.0.32 | fixed by backport - .NET vulnerable (8.0.33 not yet in the archive) |
| AlmaLinux 8.10 | libbrotli 1.0.6-5.el8_10, Node.js 10.24.0 (own decoder), python3-brotli | library and Brotli fixed by backport - Node.js 10 vulnerable (end of life, own decoder) |
| AlmaLinux 9.8 | libbrotli 1.0.9-10.el9_8.1, Node.js 16.20.2 (linked), python3-brotli, dotnet-runtime-8.0 8.0.32 | fixed by backport - .NET vulnerable |
| AlmaLinux 10.2 | libbrotli 1.1.0-8.el10_2.1, Node.js 22.23.2 (linked), python3-brotli | fixed by backport |
| Fedora 44 | libbrotli 1.2.1, Node.js 22.23.1 (linked), python3-brotli 1.2.1 | fixed by version |
| Amazon Linux 2023 | libbrotli 1.1.0-1.amzn2023.0.1, Node.js 18.20.8 (linked) | vulnerable - no fixed package yet, Node.js through the library |
| Alpine 3.22 | brotli-libs 1.1.1, Node.js 22.23.4 (linked), py3-brotli 1.1.1 | fixed by version |
Official images and PyPI
| Image | Decoders | Plug-in result |
|---|---|---|
node:24.22.0-slim | Node.js 24.22.0 (own decoder) | vulnerable |
node:24.22.1-slim | Node.js 24.22.1 (own decoder) | fixed by version |
node:20-alpine | Node.js 20.20.2 (own decoder) | vulnerable - end of life, no fix |
node:24.22.0-slim, binary moved to /home/dev/.nvm/... (owned by a user) | Node.js 24.22.0 | vulnerable - version read from the binary, not run |
python:3.12-slim + pip install Brotli==1.2.0 brotlicffi==1.2.0.0, venv with Brotli 1.1.0 in /srv/app/venv | Brotli, brotlicffi (own decoders) | vulnerable (the venv found through its running process) |
python:3.12-slim + current PyPI | Brotli 1.2.1, brotlicffi 1.2.1.0 | fixed by version |
mcr.microsoft.com/dotnet/runtime:8.0.32 / :8.0 | .NET 8.0.32 / 8.0.33 | vulnerable / fixed by version |
The Checkmk site itself (2.5.0p17) ships no Brotli package in its Python. The plug-in has not yet run on a production host outside containers - in particular not with SELinux enforcing (RHEL family); the agent normally runs unconfined there.
Download the .mkp from a release (or build it yourself, see
Development).
Setup > Maintenance > Extension packages > Upload package, or on the command line inside the site:
mkp add broccoli2shell-<version>.mkp
mkp enable broccoli2shell <version>
Deploy the agent plug-in to the hosts you want to check:
Run a service discovery on the hosts. Every decoder gets its own service, plus one
Broccoli2Shell restart service per host.
Optional: adjust the states in Setup > Services > Service monitoring rules > Broccoli2Shell (CVE-2026-111497) and Broccoli2Shell restart.
Copy package/agents/plugins/broccoli2shell into a cache-interval subdirectory of the
agent's plug-in directory and make it executable:
install -m 755 broccoli2shell /usr/lib/check_mk_agent/plugins/3600/broccoli2shell
The 3600 directory makes the agent run it in the background once an hour and serve the
cached result in between. Do not put it directly into plugins/: it reads large binaries
and the memory map of every process, which is too much for every agent query.
| Service | One per | States (default, configurable) |
|---|---|---|
Broccoli2Shell <path> | decoder, e.g. Broccoli2Shell /usr/lib/x86_64-linux-gnu/libbrotlidec.so.1, Broccoli2Shell /usr/bin/node, Broccoli2Shell /usr/lib/python3/dist-packages (brotli), Broccoli2Shell /usr/lib/dotnet (.NET 8.0) | OK fixed or not affected - CRIT vulnerable, loaded by a running process - CRIT vulnerable, not loaded - UNKNOWN version or linked library not determinable |
Broccoli2Shell restart | host with a decoder | OK - CRIT processes still use a replaced decoder |