On October 21, 2026, the PHP project shipped an emergency security release fixing two critical remote code execution flaws: CVE-2026-109618 (RCE via out-of-memory corruption) and CVE-2026-109619 (RCE via stale global state). Both are rated CVSS 9.2, both need no authentication, and security researchers, who call the pair "PHP2Shell", have already seen exploitation attempts in the wild. If your Ubuntu server runs PHP 8.2, 8.3, 8.4, or 8.5, you should patch today. This guide walks you through checking your exact PHP version, upgrading to the fixed release (8.2.35 / 8.3.36 / 8.4.27 / 8.5.12), restarting every PHP worker, and verifying the fix the right way.
Why this patch cannot wait
Both flaws live in the PHP engine itself, not in your application code. The demonstrated risk is highest for Apache with mod_php, where an unauthenticated request can trigger code execution before your application even starts, but PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed are all affected. That means no WordPress plugin, firewall rule, or password change can substitute for the patch. The only complete fix is the updated PHP binary, plus a restart of every running PHP worker.
Prerequisites
- Ubuntu 22.04 or 24.04 server with sudo access over SSH.
- PHP 8.2 or newer installed via APT (PHP-FPM and/or Apache mod_php).
- Know which sites on the server run PHP, so you can test them afterwards.
- A backup or snapshot before touching production is always a good idea.
Step 1: Check your current PHP version (CLI and web)
The version on the command line and the version your web server actually runs can differ, because they are separate SAPIs. Check both, starting with the CLI:
php -v
This prints the CLI build, for example PHP 8.4.26. Now check what the web server serves. Create a temporary phpinfo page in your web root:
echo '<?php phpinfo();' | sudo tee /var/www/html/phpinfo.php
Open https://your-server/phpinfo.php in a browser and note the version at the top. If it shows anything below the fixed release for your branch, you are vulnerable. Keep this page for the verification step later, and remember to delete it at the end.
Step 2: Identify your SAPI and branch
Find out how PHP is served on this machine, because the restart step depends on it:
systemctl list-units 'php*-fpm' --no-pager
This lists running PHP-FPM pools, for example php8.4-fpm.service. If you use Apache with mod_php instead, check the loaded module:
apache2ctl -M | grep -i php
Now match your branch to the fixed release from the October 21 announcement:
- PHP 8.2: vulnerable up to 8.2.34, fixed in 8.2.35
- PHP 8.3: vulnerable up to 8.3.35, fixed in 8.3.36
- PHP 8.4: vulnerable up to 8.4.26, fixed in 8.4.27
- PHP 8.5: vulnerable up to 8.5.11, fixed in 8.5.12
On PHP 8.1 or older there is no official release; you need a vendor backport or an upgrade to a supported branch, which we cover briefly in the FAQ.
Step 3: Update package lists and upgrade
On many Ubuntu servers the fixed build is already in the repositories. Refresh the package index and upgrade:
sudo apt update && sudo apt upgrade -y
This upgrades every package with a newer version available, including PHP if your repository carries the fix. To upgrade only PHP-related packages, you can use sudo apt install --only-upgrade 'php*' instead. Then check which version APT would install for your branch:
apt policy php8.4
Look at the Candidate line. If it shows 8.4.27 or newer, install it and move to Step 5. If the candidate is still below the fixed release, your repositories do not have the patch yet, so continue to Step 4.
Step 4: Add the ondrej/php PPA if the fix is not in your repos
The widely used ondrej/php PPA tracks upstream PHP releases closely and already carries the fixed builds. Add it and refresh:
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
The first command registers the PPA; the second pulls its package lists. Now check the candidate again:
apt policy php8.4 | grep Candidate
You should now see 8.4.27 or newer. Install the PHP packages for your branch:
sudo apt install php8.4
This pulls the latest 8.4.x from the PPA, which includes the security fix. If you want to pin the exact fixed release, use APT version globbing, for example sudo apt install php8.4=8.4.27*. Repeat for the SAPIs and extensions you use, such as php8.4-fpm or libapache2-mod-php8.4.
Step 5: Restart PHP-FPM pools and the web server
This step is not optional. Running PHP workers keep the old, vulnerable code loaded in memory, so the patch does nothing until they restart. Restart the FPM pool for your branch:
sudo systemctl restart php8.4-fpm
Then restart the web server. For Apache:
sudo systemctl restart apache2
For Nginx, a reload is enough since Nginx itself does not embed PHP, but the php-fpm restart above is the one that matters:
sudo systemctl reload nginx
If you run multiple PHP versions side by side, restart each FPM pool you use, for example php8.3-fpm and php8.4-fpm.
Step 6: Verify the fix through the web server
Reload the phpinfo page you created in Step 1. The version at the top must now show the fixed release (8.2.35, 8.3.36, 8.4.27, or 8.5.12 for your branch). Checking through the web server matters: php -v on the CLI can show the new version while an unrestarted FPM pool still serves the old one. Once confirmed, delete the phpinfo page immediately, it discloses server details to anyone who finds it:
sudo rm /var/www/html/phpinfo.php
Verify it worked
Run these three checks and confirm all of them before calling the job done:
php -v
systemctl status php8.4-fpm --no-pager
The first confirms the CLI build is at or above the fixed release; the second confirms the FPM pool is active and running the new binary (check the start time to prove it restarted). Third, load one of your real PHP pages or a quick curl -I https://your-site/ and confirm the site responds normally. Finally, make sure the temporary phpinfo.php file is gone.
Common issues & fixes
1. The site still shows the old PHP version after upgrading
You upgraded the package but did not restart the right FPM pool, or you have more than one pool running. List them and restart each one you use:
systemctl list-units 'php*-fpm.service' --no-pager
sudo systemctl restart php8.4-fpm
2. Apache still loads the old mod_php
Check which PHP module Apache actually loaded with apache2ctl -M | grep -i php. If it shows the old version, install the matching module package and restart Apache:
sudo apt install libapache2-mod-php8.4
sudo systemctl restart apache2
3. APT reports held or broken packages after adding the PPA
A package pinned by apt-mark hold will block the upgrade. Inspect holds and the candidate version:
apt-mark showhold
apt policy php8.4
Unhold the package with sudo apt-mark unhold php8.4 and run the install again.
4. Composer fails its platform check after the minor bump
After a PHP version change, composer install can fail with "your php version does not satisfy" if the lock file pins platform requirements. Regenerate the lock data against the new runtime:
composer update --lock
composer check-platform-reqs
The first command refreshes the lock file; the second confirms every requirement is satisfied.
5. You left phpinfo.php publicly accessible
That file reveals your exact PHP version, loaded modules, and paths to anyone who guesses the URL. Remove it the moment verification is done:
sudo rm /var/www/html/phpinfo.php
Conclusion
The October 2026 PHP release is one of those updates you do not postpone: two unauthenticated RCE flaws at CVSS 9.2, with exploitation already observed in the wild. The fix itself is simple: update to 8.2.35, 8.3.36, 8.4.27, or 8.5.12 for your branch, restart every PHP-FPM pool and your web server, and verify through the web server rather than the CLI. Servers on PHP 8.1 or older should plan an upgrade to a supported branch, since no official patch exists for them. If you manage client servers and want patching handled without the 2 AM scramble, XpertBees offers managed Ubuntu server maintenance and security updates.

