Sign Up
GPU ServerDedicated Server
TicketSign Up

Is Your VPS Safe from PHP2Shell? How to Audit and Patch Your Web Servers

CVE-2026-109618/19 lets attackers run code via PHP. Check the PHP your web server really uses, update to 8.2.35+, restart workers and verify.

Introduction: Patch First, Read Later

If you run PHP on a public server, stop and check it today. PHP2Shell is a pair of critical PHP flaws that let an unauthenticated attacker run code on your server, and attacks started within a day of the patch. CISA added both CVEs to its Known Exploited Vulnerabilities (KEV) catalog on 26 October 2026.

This guide is the short path: confirm which PHP actually serves your sites, update it, restart every worker, verify, and look for signs that someone got in first.

What Is PHP2Shell?

PHP2Shell is the name for two PHP core vulnerabilities, CVE-2026-109618 and CVE-2026-109619, that can allow unauthenticated remote code execution on any PHP installation serving web requests. Both are rated CVSS v4.0 9.2 (Critical) in PHP's security advisories.

The two PHP2Shell vulnerabilities
CVE-2026-109618CVE-2026-109619
Bug typeMemory corruption after an out-of-memory error during request handlingUse-after-free: stale request state is reused by a later operation on the same worker
Typical triggerCrafted multipart (upload) requests, for example with huge header counts or deeply nested field namesSession upload progress handling, the default-on session.upload_progress feature
AdvisoryGHSA-w8hw-w9fx-j79wGHSA-6wmf-4rv5-p3rp
Authentication neededNoneNone

Which setups are at risk? Every PHP install that serves web traffic: PHP-FPM, Apache mod_php, php-cgi, LiteSpeed and FrankenPHP. Researchers at watchTowr rate Apache mod_php as the most urgent, because an attack can succeed before any of your application's own code has run. The PHP CLI used for cron jobs and scripts does not serve web requests, but it is often a different build, which is exactly why version checks go wrong (see the audit below). Wiz Research's write-up and Akamai's analysis cover the technical detail.

Timeline

  • 20 Oct 2026: details leak on social media ahead of the planned 22 October disclosure.
  • 21 Oct 2026, 14:00 UTC: PHP ships emergency releases; Ubuntu publishes USN-8948-1.
  • 21 Oct 2026 onward: watchTowr observes exploitation in the wild; proof-of-concept scripts spread quickly on GitHub.
  • 26 Oct 2026: CISA adds both CVEs to the KEV catalog.

Which PHP Versions Are Affected?

Every PHP release before 8.2.35, 8.3.36, 8.4.27 and 8.5.12 is affected, including all of PHP 8.1, 8.0, 7.x and 5.x. Only these upstream releases fix both flaws:

PHP2Shell affected and fixed PHP versions
PHP branchVulnerableFixed upstream version
8.5below 8.5.128.5.12
8.4below 8.4.278.4.27
8.3below 8.3.368.3.36
8.2below 8.2.358.2.35
8.1, 8.0, 7.4allNo upstream release; use a vendor backport or upgrade
7.3 and olderallNo fix; upgrade or use a paid extended-support build

Distro packages keep their old version numbers. Ubuntu 24.04 reports PHP 8.3.6 even when patched, because the fix is backported. Always check the full package version against your vendor's advisory, not the upstream number.

How to Audit Your Server for PHP2Shell

To check if your VPS is exposed, find every PHP build on the server, identify the one(s) actually serving web requests, and compare each package version with your vendor's fixed version. Running php -v alone is not enough: it shows the CLI, which is often a different build from PHP-FPM or mod_php. Run the commands below over an SSH session as a user with sudo rights.

Step 1: List every PHP build on the server

ls -1 /usr/bin/php* /usr/sbin/php-fpm* \
      /opt/remi/*/root/usr/bin/php /opt/cpanel/ea-php*/root/usr/bin/php \
      /opt/alt/php*/usr/bin/php /opt/plesk/php/*/bin/php 2>/dev/null

Servers with control panels or multiple PHP versions commonly have five or more builds. Each one that any site uses needs patching.

Step 2: Check PHP version CLI vs FPM vs mod_php

php -v                                   # CLI only
ps -eo user,cmd | grep -E 'php-fpm|php-cgi|lsphp' | grep -v grep   # running web workers
php-fpm8.3 -v 2>/dev/null || php-fpm -v  # FPM binary (Debian/Ubuntu name first, then RHEL)
apachectl -M 2>/dev/null | grep -i php   # loaded php_module = mod_php is in use

If apachectl -M lists a PHP module, you are running mod_php, the highest-risk setup. Patch that host first.

The most reliable check asks the web server itself. Create a temporary file with a random name, read it once, then delete it:

F=/var/www/html/chk-$(openssl rand -hex 8).php
echo '<?php echo PHP_VERSION, " ", PHP_SAPI, " upload_progress=", ini_get("session.upload_progress.enabled");' | sudo tee "$F" >/dev/null
curl -s "http://localhost/$(basename "$F")"; echo
sudo rm -f "$F"

Repeat for each virtual host or PHP pool that uses a different version.

Step 3: Check the package version, not just the PHP number

# Debian / Ubuntu
dpkg -l | awk '/^ii/ && /php[0-9.]+-(fpm|cli|common)|libapache2-mod-php/ {print $2, $3}'
zgrep -m1 CVE-2026-109618 /usr/share/doc/php8.3-common/changelog.Debian.gz

# RHEL, AlmaLinux, Rocky, CloudLinux, cPanel
rpm -qa | grep -E '^(php|ea-php|alt-php)' | sort
rpm -q --changelog php-fpm | grep -m1 -E 'CVE-2026-10961(8|9)'

A changelog line that names the CVE means the fix is in, even if the version still reads 8.1 or 8.3. No output means you are not patched yet.

Step 4: Look for signs of compromise

Attacks began within a day of the patch, so a server patched on 25 October may already have been hit. Check:

# PHP workers crashing (failed exploit attempts often segfault)
grep -E 'SIGSEGV|Segmentation fault' /var/log/php*-fpm.log /var/log/apache2/error.log /var/log/httpd/error_log 2>/dev/null | tail

# PHP files created or changed since the leak
find /var/www /home/*/public_html -type f -name '*.php' -newermt '2026-10-20' 2>/dev/null

# Common web shell patterns
grep -rlE 'eval\(base64_decode|assert\(\$_(GET|POST|REQUEST)|system\(\$_(GET|POST|REQUEST)' /var/www /home/*/public_html 2>/dev/null

# Unexpected outbound connections from the web user
sudo ss -tpn | grep -E 'php|www-data|apache|nginx'

Also review new cron jobs (crontab -l -u www-data), new SSH keys and new system users. In access logs, look for bursts of multipart POST requests to upload endpoints, especially ones that end in 500 errors. On WordPress sites, a malware scan adds a second opinion. If you find a web shell, treat the server as compromised: isolate it, rotate every secret it held, and rebuild from a clean image rather than cleaning in place.

Why checking PHP version in the CLI is not enough: the CLI can be patched while PHP-FPM serving websites is still vulnerable.
Example: php -v reports a patched 8.3.36 CLI while the PHP-FPM build serving the sites is still 8.3.30.

How to Fix PHP2Shell on Your VPS

The only complete fix is updating PHP to a patched build and then restarting every PHP worker. Configuration changes reduce risk but do not close the hole.

Ubuntu and Debian

sudo apt update
sudo apt install --only-upgrade $(dpkg -l | awk '/^ii/ && $2 ~ /^(php|libapache2-mod-php)/ {print $2}')

Fixed package versions from the Ubuntu and Debian security trackers:

Fixed PHP package versions on Ubuntu and Debian
DistributionPackageFixed versionAdvisory
Ubuntu 26.04 LTSphp8.58.5.4-0ubuntu1.5USN-8948
Ubuntu 24.04 LTSphp8.38.3.6-0ubuntu0.24.04.13USN-8948
Ubuntu 22.04 LTSphp8.18.1.2-1ubuntu2.28USN-8948
Debian 13 (trixie)php8.48.4.27-1~deb13u1DSA-6574-1
Debian 12 (bookworm)php8.28.2.35-1~deb12u1DLA-4848-1

If you use a third-party repository (for example the Ondřej Surý PPA or sury.org), confirm it now ships at least 8.2.35, 8.3.36, 8.4.27 or 8.5.12 for your branch.

RHEL, AlmaLinux and Rocky Linux

sudo dnf clean all && sudo dnf upgrade 'php*'
rpm -q --changelog php-fpm | grep -m1 -E 'CVE-2026-10961(8|9)'

If you use Remi's repository for newer PHP versions, the same dnf upgrade pulls the upstream fixed releases. For the distribution's own AppStream PHP, check your vendor's errata before assuming a fix is out.

cPanel / WHM and CloudLinux

# EasyApache 4 PHP (AlmaLinux, Rocky, CloudLinux 8+)
dnf clean all && dnf upgrade 'ea-php*'
# CloudLinux alt-php
dnf clean all && dnf upgrade 'alt-php*'
# Verify a backported branch, e.g. PHP 8.1
rpm -q --changelog ea-php81-php-cli | grep -m1 CVE-2026-109618

cPanel shipped the upstream fixes for ea-php82 to ea-php85 and backports for ea-php74, ea-php80 and ea-php81 (8.1.34-5), as summarised here. Admins have reported that /scripts/upcp --security updated cPanel's own PHP but not the EasyApache packages, and CloudLinux notes that security-only updates such as yum --security do not list them, so use the plain upgrade commands above. On CentOS 7 or CloudLinux 7, use yum update instead of dnf upgrade. New to WHM? Our cPanel guide covers the basics.

Plesk and Docker

docker compose build --pull --no-cache && docker compose up -d

Restart every PHP worker

An update on disk does not patch running processes. Restart all of them:

sudo systemctl restart 'php*-fpm.service'   # every PHP-FPM version (Debian/Ubuntu naming)
sudo systemctl restart php-fpm              # RHEL family
sudo systemctl restart apache2              # if Apache runs mod_php (httpd on RHEL)
/scripts/restartsrv_apache_php_fpm && /scripts/restartsrv_httpd   # cPanel

Run only the lines that match your server; a restart of a service you do not have just reports an error.

If you cannot patch today

These settings from the published mitigation guidance reduce exposure until you can update. They are not a fix.

  • Set session.upload_progress.enabled = 0 in the main php.ini or FPM pool config, then restart workers. Do not rely on ini_set() or .user.ini.
  • Keep post_max_size small (8M if the site takes no uploads, 32M if it does) and enforce request-size limits at Nginx or Apache (see our web server comparison and Nginx reverse proxy guide).
  • Block multipart/form-data at the proxy for sites that never accept uploads.
  • On PHP 8.5, set fatal_error_backtraces = 0.
  • Restrict public access to servers that cannot be updated, or move them behind a VPN.
Four-step PHP2Shell patch checklist: inventory PHP builds, update, restart workers and verify.
Inventory, update, restart, verify: skip any step and the server can stay exposed.

How Do I Check If My VPS Is Patched?

Your VPS is patched when the PHP build serving web requests reports a fixed version (or a vendor changelog entry for both CVEs) and no PHP process is still running the old binary. Verify all three:

  • Web-served version. Re-run the temporary-file check from Step 2. It should show 8.2.35+, 8.3.36+, 8.4.27+ or 8.5.12+, or a distro build whose changelog names CVE-2026-109618 and CVE-2026-109619.
  • No stale workers. Processes started before the update still map the old library. This should print nothing:
sudo lsof -nP 2>/dev/null | awk '$4=="DEL" && /php/' | head
  • Every pool and version. Repeat for each PHP version a site uses, including old ones kept for a single legacy app.

Harden after patching

  • Leave PHP 8.1 and older. Without upstream releases, you depend on backports for every future bug. Plan the move to 8.3 or newer.
  • Prefer PHP-FPM over mod_php. FPM isolates PHP from the web server and lets you run each site's pool as its own user.
  • Disable upload progress where unused. session.upload_progress.enabled = 0 removes one attack path permanently for sites that do not show upload progress bars.
  • Enable automatic security updates for PHP packages (unattended-upgrades on Debian/Ubuntu, dnf-automatic on the RHEL family).
  • Monitor for crashes and new files. File-integrity monitoring and log rules in tools such as Wazuh can alert on new PHP files in web roots and PHP worker segfaults.
  • Put an edge filter in front. A WAF or DDoS-filtered network can absorb exploit scanning, but it complements patching rather than replacing it.

Running sites on a Linux KVM VPS or a cPanel VPS means you control the PHP versions yourself, so keep this checklist for the next advisory too.

Sources

Frequently Asked Questions

Is the PHP CLI affected by PHP2Shell?

The exploit paths need PHP to handle web requests (FPM, mod_php, CGI, LiteSpeed, FrankenPHP). The CLI shares the same source, so update it too, but the urgent target is whichever PHP serves your websites.

Is Nginx with PHP-FPM safe?

No. PHP-FPM is affected. Its startup behavior blocks one out-of-memory path, but remote code execution through the session upload-progress path has been validated on FPM under suitable application conditions. Patch and restart FPM.

Does a WAF protect me from PHP2Shell?

Partly. WAF rules and request-size limits can block known exploit patterns, and attackers are already trying to evade them. Treat a WAF as a short-term shield, not a fix.

Do I need to reboot the VPS?

Not usually. Restarting PHP-FPM, Apache or LiteSpeed is enough, as long as no PHP process still maps the old library. Reboot if you cannot confirm that.

My server was unpatched for days. Was it hacked?

Not necessarily, but check. Run the compromise checks in Step 4, and if anything looks wrong, rebuild from a clean image and rotate database passwords, API keys and SSH keys.

Privacy preferences

Essential cookies keep the site working and remember your choices. Optional purposes follow the site's collection policy unless you refuse them.

We remember your choices for 180 days. Permitted acquisition information is kept for up to 30 days. Read our privacy policy.