Discover Centmin Mod today
Register Now

Security Brotli CVE-2026-111497 fixes for Nginx and PHP-FPM

Discussion in 'Centmin Mod News' started by eva2000, Oct 26, 2026 at 9:18 AM.

Thread Status:
Not open for further replies.
  1. eva2000

    eva2000 Administrator Staff Member

    60,106
    12,587
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +19,244
    Local Time:
    5:01 PM
    Nginx 1.31.x
    MariaDB 10.x/11.4+/12.3+
    Google's brotli compression library has a decoder out-of-bounds write security vulnerability, CVE-2026-111497 in brotli 1.0.3 to 1.2.0. It's fixed in brotli 1.0.10, 1.1.1 and 1.2.1. In Centmin Mod, brotli is used in two places: by Nginx's optional ngx_brotli module, and by PHP-FPM, which loads the operating system's brotli library through curl, freetype (GD) and libjxl (ImageMagick).

    Centmin Mod 132.00stable, 140.00beta01 and 141.00beta01 now fix both. Run cmupdate first. Then rebuild Nginx with centmin.sh menu option 4 if you use Nginx brotli, and rebuild PHP with centmin.sh menu option 5. You can also switch PHP-FPM over straight away without rebuilding PHP, as shown below.

    Why PHP-FPM matters most

    • curl decodes brotli that remote servers send. Any PHP code that fetches outside URLs with curl can be sent a brotli response by a malicious server, and the decoding happens inside a PHP-FPM worker. Examples are XenForo's image proxy and link previews, and WordPress plugins that fetch remote feeds or APIs.
    • On AlmaLinux and Rocky Linux 8 and 9, curl also decodes brotli that a server forces on it with Transfer-Encoding: br, even when the PHP code never asked for decoding. Turning off decoding in your application isn't enough there. EL10's curl 8.12.1 ignores that header.
    • At the time of writing, the AlmaLinux and Rocky Linux brotli packages are 1.0.6 (EL8), 1.0.9 (EL9) and 1.1.0 (EL10), and none of them includes the fix yet.

    Nginx is lower risk. ngx_brotli only uses the brotli encoder to compress responses, so Nginx never decodes brotli it receives. The Nginx build does, though, install the brotli library and command-line tool, including the vulnerable decoder, under /usr/local/nginx-dep.

    What was fixed

    Nginx brotli (centmin.sh menu option 4)

    • Nginx brotli is optional and off by default (NGINX_LIBBROTLI='n'), so this only applies if you enabled it.
    • On EL7 to EL10, the build uses the brotli bundled with ngx_brotli. Upstream updated that from brotli 1.1.0 to 1.2.1 on 22 October 2026, so Nginx brotli builds made before then bundle an unfixed brotli.
    • The older build method, used when NGINX_BROTLI_NEW_METHOD='n' and always on CentOS 6, now pins brotli 1.0.10 instead of a vulnerable 2022 snapshot.
    • A new version check stops the Nginx build if the brotli it built isn't 1.0.10+, 1.1.1+ or 1.2.1+.

    PHP-FPM (centmin.sh menu option 5)

    • A new tool, tools/phpfpm-brotli.sh, builds brotli 1.2.1 into /opt/brotli_php and points PHP-FPM at it with a systemd setting (LD_LIBRARY_PATH in a php-fpm.service drop-in). That covers curl, freetype and libjxl inside PHP-FPM at once, with no PHP recompile.
    • It's on by default through the new setting PHPFPM_BROTLI_SOURCE='y', and is applied during centmin.sh menu option 5 PHP upgrades and new installs.
    • Before switching, it checks that php-fpm -t loads the new brotli. It then restarts PHP-FPM and confirms the running processes use the new brotli. If anything fails, it falls back to the distro brotli, and it never makes a PHP upgrade fail.
    • It retires itself. Once the distro brotli package includes the fix, the next menu option 5 run removes the override and PHP-FPM goes back to the distro library.
    • It only acts where PHP-FPM actually loads brotli, which means AlmaLinux and Rocky Linux 8, 9 and 10. It skips CentOS 6, which has no systemd.
    • While the override is in effect, the end of a menu option 5 PHP upgrade shows its status.

    Who is affected?

    • Nginx with brotli: Affected if NGINX_LIBBROTLI='y' and Nginx was built before 22 October 2026 or with the older method; Fix cmupdate + menu option 4
    • PHP-FPM on EL8, EL9 and EL10: Affected always, PHP-FPM loads the distro brotli; Fix cmupdate + menu option 5, or tools/phpfpm-brotli.sh on
    • PHP-FPM on CentOS 6 and 7: Affected normally not, their curl and freetype predate brotli support; Fix not needed; on CentOS 7, tools/phpfpm-brotli.sh status shows whether PHP-FPM loads brotli
    • PHP brotli extension: Affected only if PHP_BROTLI='y' (off by default), it bundles its own brotli for brotli_uncompress(); Fix menu option 5 rebuilds it from the latest php-ext-brotli code, which bundles brotli 1.2.1

    Updating

    Code (Text):
    cmupdate
    centmin


    Then run menu option 4 to rebuild Nginx if you use Nginx brotli, and menu option 5 to rebuild PHP.

    To switch PHP-FPM over right away without rebuilding PHP:

    Code (Text):
    cmupdate
    /usr/local/src/centminmod/tools/phpfpm-brotli.sh on


    This restarts PHP-FPM.

    How to verify the fixes

    Nginx

    Code (Text):
    nginx -V 2>&1 | grep -o ngx_brotli
    /usr/local/nginx-dep/bin/brotli -V
    grep -h 'CVE-2026-111497' "$(ls -1t /root/centminlogs/*_nginx_brotli.log | head -1)"


    • If the first command prints nothing, your Nginx has no brotli module and there's nothing to fix.
    • The version should be brotli 1.2.1 on EL7 to EL10, or brotli 1.0.10 on CentOS 6. Anything older needs a menu option 4 rebuild.
    • The build log line should look like brotli 1.2.1 includes the CVE-2026-111497 fix.

    PHP-FPM

    Code (Text):
    /usr/local/src/centminmod/tools/phpfpm-brotli.sh status


    Example output from an AlmaLinux 9 server:

    Code (Text):
    override:      on, /etc/systemd/system/php-fpm.service.d/brotli-source.conf
    build:         /opt/brotli_php/1.2.1-20261025222455 (brotli 1.2.1)
    distro brotli: libbrotli-1.0.9-10.el9_8, lacks the CVE-2026-111497 fix
    setting:       PHPFPM_BROTLI_SOURCE='y'
    environment:   LD_LIBRARY_PATH=/opt/brotli_php/1.2.1-20261025222455/lib64
    php-fpm ELF:   RUNPATH /usr/local/libgd/2.3.3/lib:/usr/local/lib64:/opt/remi/libzip/lib64
    php-fpm maps:
      /opt/brotli_php/1.2.1-20261025222455/lib64/libbrotlicommon.so.1.2.1
      /opt/brotli_php/1.2.1-20261025222455/lib64/libbrotlidec.so.1.2.1
      /opt/brotli_php/1.2.1-20261025222455/lib64/libbrotlienc.so.1.2.1


    Look for override: on, and under php-fpm maps only /opt/brotli_php/.../libbrotli*.so.1.2.1 lines, with no /usr/lib64/libbrotli lines.

    The same checks without the tool:

    Code (Text):
    awk '$6 ~ /libbrotli/ {print $6}' /proc/$(systemctl show -p MainPID php-fpm | cut -d= -f2)/maps | sort -u
    systemctl show -p Environment php-fpm
    /opt/brotli_php/current/bin/brotli -V
    grep 'php-fpm brotli override' "$(ls -1t /root/centminlogs/*_php_upgrade.log | head -1)"


    These checks look reasonable but mislead:

    • ldd /usr/local/sbin/php-fpm shows the distro brotli in /usr/lib64, because ldd runs without PHP-FPM's systemd setting.
    • PHP's curl_version() doesn't show which brotli library is loaded.
    • Running php from the command line doesn't use the override.

    PHP command-line cron jobs

    The override covers PHP-FPM only. PHP scripts that cron runs with the php command don't get it. One example is XenForo's job runner when its job trigger is set to server-based. Add the prefix to those cron lines:


    Code (Text):
    env LD_LIBRARY_PATH=/opt/brotli_php/current/lib64 /usr/local/bin/php /path/to/cmd.php xf:run-jobs


    /opt/brotli_php/current isn't a real directory. It's a symlink the tool keeps pointed at the active brotli build, and each build has its own directory such as /opt/brotli_php/1.2.1-20261025222455. Because the cron line uses the symlink, it keeps working when a later build lands in a new directory. To see which build it points at:

    Code (Text):
    readlink -f /opt/brotli_php/current


    When the override is turned off or retires itself, the tool removes the symlink. The prefix then does nothing and PHP falls back to the distro brotli, so remove the prefix from your cron lines at that point.

    When AlmaLinux and Rocky Linux ship a fixed brotli

    A dnf update of brotli doesn't touch the override, so PHP-FPM keeps using brotli 1.2.1, which is fixed. The next menu option 5 run, or tools/phpfpm-brotli.sh on, detects the distro fix and removes the override. tools/phpfpm-brotli.sh status also tells you when the distro package has caught up.

    Turning the PHP-FPM override off

    Code (Text):
    /usr/local/src/centminmod/tools/phpfpm-brotli.sh off


    Also set PHPFPM_BROTLI_SOURCE='n' in /etc/centminmod/custom_config.inc, or the next menu option 5 run turns the override back on.

    If you can't update right away

    In PHP code you control, curl's CURLOPT_HTTP_CONTENT_DECODING => false option stops curl decoding brotli, including the forced Transfer-Encoding: br case on EL8 and EL9. With Guzzle, set both 'decode_content' => false and 'curl' => [CURLOPT_HTTP_CONTENT_DECODING => false]. On EL8 and EL9, 'decode_content' => false on its own isn't enough. This only protects the code you change, so update Centmin Mod as soon as you can.

    References


    PHP-FPM upgrade issues

    If you have issues with PHP-FPM upgrades via centmin.sh menu option 5, check your PHP upgrade logs for details https://community.centminmod.com/threads/how-to-troubleshoot-php-installs-upgrades.17857/
     
  2. eva2000

    eva2000 Administrator Staff Member

    60,106
    12,587
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +19,244
    Local Time:
    5:01 PM
    Nginx 1.31.x
    MariaDB 10.x/11.4+/12.3+
    XenForo Relevance

    XenForo fetches content from other sites for features such as the image proxy, rich link previews and media embeds, and some of those URLs come from your members. These requests run in PHP-FPM, so the PHP-FPM override fix above covers them once it's on. Check it with tools/phpfpm-brotli.sh status as shown above.

    Two cases run PHP from the command line instead, so they need the LD_LIBRARY_PATH prefix from the PHP command-line cron jobs section:
    • The cmd.php xf:run-jobs cron line, if Setup > Options > System and performance > Job run trigger is set to Server based trigger.
    • XenForo commands you run yourself with cmd.php, such as rebuilds and imports.
    If you can't update Centmin Mod right away, temporarily turn off Setup > Options > Image and link proxy > Proxy images and Setup > Options > Messages > Unfurl URL to a rich preview automatically. That reduces the exposure but doesn't remove it, so update as soon as you can.
     
Thread Status:
Not open for further replies.