DEV Community

Cover image for PHP2Shell: why php -v can't tell you if you're patched
Danila Vershinin
Danila Vershinin

Posted on Originally published at getpagespeed.com AI-assisted

PHP2Shell: why php -v can't tell you if you're patched

PHP2Shell is two critical PHP bugs disclosed on October 21, 2026: CVE-2026-109618 (remote code execution via out-of-memory corruption) and CVE-2026-109619 (remote code execution via stale global state). Both are CVSS 4.0 9.2 and need no authentication. Attacks are already happening.

Upstream fixed only PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Everything else depends on your vendor.

The version-number trap

Most people check with php -v. On a patched Ubuntu 24.04 that still prints PHP 8.3.6, because Ubuntu backported the fix into its own package (8.3.6-0ubuntu0.24.04.13). Debian, RHEL, AlmaLinux, Rocky, Remi and others do the same in different ways. A version scanner that only reads the upstream number flags patched servers as vulnerable, and can wave through an unpatched EOL build.

The package release is what matters:

rpm -qa 'php*'        # RHEL, CentOS, Alma, Rocky
dpkg -l 'php*'        # Debian, Ubuntu
Enter fullscreen mode Exit fullscreen mode

I built a free PHP2Shell checker that reads that output in your browser and knows each vendor's fixed builds. Nothing you paste leaves the page.

What NGINX can and can't do

We tested edge mitigations on Rocky Linux 10 with NGINX 1.30 and PHP-FPM 8.3. Three results surprised me:

  1. Stock NGINX already blunts one attack path. CVE-2026-109618 can use a multipart body "without a usable declared content length". With the default fastcgi_request_buffering on, NGINX de-chunks the body and hands PHP-FPM the real CONTENT_LENGTH. Keep buffering on for PHP.
  2. client_max_body_size is the best single lever. NGINX rejects an oversized chunked body with 413 before PHP parses a byte.
  3. The popular PHP_VALUE trick does not work. fastcgi_param PHP_VALUE "session.upload_progress.enabled=0" left upload progress enabled in our test. Set it in the FPM pool instead:
php_admin_flag[session.upload_progress.enabled] = off
Enter fullscreen mode Exit fullscreen mode

The advisory also warns that per-request INI values from the frontend which raise a warning are themselves a trigger for CVE-2026-109619, so audit what you send:

grep -rn 'PHP_VALUE\|PHP_ADMIN_VALUE' /etc/nginx /etc/php-fpm.d /etc/php
Enter fullscreen mode Exit fullscreen mode

None of this replaces updating PHP. Edge rules stop the known request shapes, and the advisories document paths that need no special upload at all.

Still on CentOS 7?

Remi stopped building for CentOS 7 in June 2024, and php.net shipped nothing for PHP 7.x there. GetPageSpeed publishes free patched PHP 5.6, 7.0, 7.3, 7.4 and 8.0 builds for CentOS 7, plus a PHP 8.4.27 stack:

yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum --enablerepo=getpagespeed-extras-php74 upgrade 'php-*'
systemctl restart php-fpm
Enter fullscreen mode Exit fullscreen mode

Then restart every PHP process, whatever your platform. Running workers keep the old code in memory.

The full write-up has fixed versions per distro, the ModSecurity rules we tested, detection commands and a timeline: PHP2Shell: check, fix and mitigate.

Top comments (0)