Brotli CVE-2026-111497 on CentOS 7: ngx_brotli is fine, libbrotli is not
CVE-2026-111497, the Brotli bug that also goes by HTTP2Shell, Broccoli2Shell and Node2Shell, is an out-of-bounds write in the Brotli decoder (c/dec/decode.c). It affects Google Brotli 1.0.3 through 1.2.0, is fixed in 1.0.10, 1.1.1 and 1.2.1, and CISA lists it as exploited.
Most of the coverage is about Node.js. If you run NGINX on an EL box, two questions matter: is the Brotli module affected, and where does your decoder come from?
ngx_brotli: not affected
ngx_brotli compresses responses and serves .br files. It never decompresses, so it never runs the vulnerable code. F5 says the same about the NGINX Plus Brotli module (K000163902).
ldd on CentOS 7 confirms it: the filter module links only libbrotlienc and libbrotlicommon, and the static module links no Brotli library at all.
The one NGINX module that does decode is unbrotli, which decompresses Content-Encoding: br responses from upstreams. A hostile or compromised backend feeds it attacker-controlled data, so it is exposed through the system library.
What actually decodes Brotli on your server
rpm -q --whatrequires 'libbrotlidec.so.1()(64bit)' On a CentOS 7 test box that printed brotli, openssl35-libs, libcurl-latest, curl-latest and nginx-module-unbrotli. Note that rpm -q --whatrequires libbrotli prints nothing useful: packages depend on the soname, not the package name.
All of them link the system library, so one package update fixes all of them.
CentOS 7: EPEL stopped at a vulnerable build
RHEL, Rocky Linux and AlmaLinux 8 to 10 shipped fixed brotli/libbrotli within days. CentOS 7 got its Brotli from EPEL 7, which is archived. Its last build, libbrotli-1.0.9-10.el7, sits inside the affected range and will never be updated. Amazon Linux 2 servers that took Brotli from EPEL are in the same spot.
GetPageSpeed ships libbrotli 1.2.1 for CentOS 7 and Amazon Linux 2, x86_64 and aarch64, with the same package split as EPEL, so it upgrades EPEL's build in place:
yum -y install https://extras.getpagespeed.com/release-latest.rpm yum -y update libbrotli brotli rpm -q libbrotli # expect libbrotli-1.2.1-5.el7 systemctl restart nginx Free to install; commercial production use requires a subscription. Disclosure: I maintain this package.
Restart matters: a running process keeps the old library mapped. Find the stragglers with:
grep -l 'libbrotlidec.*(deleted)' /proc/[0-9]*/maps 2>/dev/null Things the library update does not cover
- Python bindings compile Brotli into their own extension. Old
python-brotliandpython34-brotli1.0.7 builds need replacing bypython2-brotli/python36-brotli1.2.1. - Bundled copies: Node.js, Firefox and anything else that vendors Brotli need their own update.
- "Block
Content-Encoding: br" only helps where the server decompresses request bodies. It does nothing for unbrotli, curl or OpenSSL, which receive Brotli from the other side of the connection.
The full write-up, with the RHEL/Alma/Rocky and Debian/Ubuntu fixed versions and how each command was tested in clean containers, is on GetPageSpeed.