PHP fix due 14:00 UTC
Traffic news · For technicians ·
php2shell: a working checklist for the next few hours
Two critical RCEs in PHP core, leaked before the fix. The release lands at 14:00 UTC and mass exploitation is expected soon after. Inventory, patching, end-of-life PHP and what a break-in looks like.
Written at 09:45 UTC on 21 October, before the advisory, and last updated at 11:05 UTC. Anything marked to confirm will be filled in from php.net after the release. The log of updates is at the foot of the page.
Where things stand
| What | Two remote code execution flaws in PHP core, reported as CVE-2026-109618 and CVE-2026-109619. The IDs are not yet on php.net. |
| Severity | CVSS v4.0 9.2 for both, per PHP's security team. The 10.0 going round came from the leak. |
| Fix | Out-of-band release, 21 Oct 14:00 UTC. PHP may ship earlier if exploitation starts. |
| Affected | To confirm. Reports and the leaked tool's own banner claim 5.4 onwards. |
| Fixed in | To confirm. Fixes are expected for the supported branches only, most likely as their next patch releases: 8.5.12, 8.4.27, 8.3.36 and 8.2.35. |
| Exploitation | None seen in the wild as of 20 Oct. watchTowr has reproduced one of the two. Sansec expects mass attacks within 15 minutes of release. |
| Workaround | None official. The flaw sits beneath the application, so no fix inside WordPress, Magento or a plugin will reach it. Two unofficial stopgaps are going round: see section 4. |
1. Find every PHP you are responsible for
The aim is a list with one row per site: host, PHP version, SAPI, who patches it. Make it now, while there is nothing to patch yet.
# The CLI's version is not necessarily the web's. Check both.
php -r 'echo PHP_VERSION, " ", PHP_SAPI, PHP_EOL;'
# Every PHP binary and FPM on the box, including control-panel builds
ls -1 /usr/bin/php* /usr/sbin/php-fpm* \
/opt/cpanel/ea-php*/root/usr/bin/php \
/opt/plesk/php/*/bin/php \
/opt/remi/php*/root/usr/bin/php 2>/dev/null
# What the web server is actually running
ps -eo pid,user,lstart,args | grep -E 'php-fpm|php-cgi|lsphp|httpd|apache2' | grep -v grep
# Containers
for c in $(docker ps -q); do
printf '%s ' "$(docker inspect -f '{{.Name}} {{.Config.Image}}' "$c")"
docker exec "$c" php -r 'echo PHP_VERSION, PHP_EOL;' 2>/dev/null || echo '(no php)'
done
Don't forget the PHP you didn't put there yourself: control panels, a forgotten staging site, a vendor appliance, and that one client on shared hosting whose login lives in somebody's inbox.
2. Line the patch up before it exists
When the release lands you want to be running one command, not reading documentation.
- Find out where your packages come from. That decides when you get the fix.
- Upstream source or the official Docker images: the fix comes at 14:00.
- Ondřej Surý's packages (
ppa:ondrej/php,packages.sury.org) usually follow upstream within hours. - Remi's repository will not have updates today, says the PHP Foundation. It is maintained by volunteers. On RHEL, Alma, Rocky or Fedora with Remi's packages, plan another source now: your distribution's own packages, or building from source.
- Distribution security teams backport to their own version numbers, so
php -vwill not show the upstream patch release. Check your distribution's security tracker for the CVE instead. - cPanel (
ea-php*), Plesk and managed hosts: their schedule, not yours. Open a ticket now.
- Book the restart. PHP-FPM and
mod_phpkeep the old code in memory until they restart. An upgraded package with an unrestarted FPM is still vulnerable. - Tell your clients now that there may be a short blip this afternoon. It is easier than explaining afterwards.
# Debian / Ubuntu
sudo apt update && apt list --upgradable 2>/dev/null | grep -i php
sudo apt install --only-upgrade 'php8.3*' # each branch you run
sudo systemctl restart php8.3-fpm # or apache2, for mod_php
# RHEL, Alma, Rocky (AppStream modules; Remi's repository has no fix today)
sudo dnf check-update 'php*'
sudo dnf upgrade 'php*'
sudo systemctl restart php-fpm
# Docker: pull, rebuild, redeploy. A running container does not change itself.
docker pull php:8.3-fpm && docker compose build --pull && docker compose up -d
Then make sure it took, from the process rather than the package manager:
# Each FPM master should have started after you upgraded
ps -o pid,lstart,args -C php-fpm8.3
3. End-of-life PHP: 8.1 and older
To confirm at 14:00, but plan on the old branches getting no upstream fix. In order of preference:
- Upgrade to a supported branch. Test plugins and themes first. Old WordPress sites that sat on 7.4 for a reason will show you the reason now.
- Take a backport from your distribution or an extended-support vendor, if you already pay for one. Check that it names these CVEs.
- Stop exposing it. Put it behind authentication or a VPN, or take it offline until it can be upgraded.
- Stop running PHP for it at all. For a brochure site nobody has edited in months, saving the rendered pages and serving them as plain files is a perfectly good emergency measure:
wget --mirror --page-requisites --adjust-extension --convert-links \
--no-parent --restrict-file-names=windows https://example.com/
Forms, search and anything else that posts back to the server will stop working, so check before you swap it in. This is the crude version of what Offramp does properly. Offramp keeps the theme's own files, measures every page against the original, and gives the editors somewhere to write.
4. Until you can patch
There is still no official workaround. Treat anything that claims to be one before the advisory with suspicion. That includes rules from WAF vendors: welcome as an extra layer, but not a substitute.
Two unofficial stopgaps are going round. Both rest on a guess at the cause: that the flaw is in how PHP handles file uploads, in the session upload progress feature. Neither PHP nor the researchers who found the bugs have confirmed that.
- Turning off upload progress:
session.upload_progress.enabled = 0inphp.ini, then restart PHP-FPM or Apache. GMO Flatt Security suggest it, and say themselves that it probably doesn't stop the attack. It costs little: few sites use the feature. It's worth it on a version that will never be patched, as long as nobody treats it as the fix. - Refusing uploads at the web server: an Apache rule that refuses every
multipart/form-dataPOST before PHP sees it. It also breaks every file upload: WordPress media, forms with attachments, shop imports. For a site that takes no uploads it may buy an afternoon, but test it first.
Things that help regardless:
- Patch internet-facing sites first, and the busiest first: they are the first to be scanned.
- Watch the clock in UTC. 14:00 UTC is 16:00 SAST, 15:00 BST and 10:00 EDT.
- Have someone available at 14:00. Fifteen minutes is not long enough to find the person with the SSH key.
5. What a break-in looks like
Attackers will want a shell and then something that survives a restart. The signs:
# Anything a PHP or web server process has started that isn't more of itself
for p in $(pgrep -f 'php-fpm|php-cgi|lsphp|apache2|httpd'); do
ps --ppid "$p" -o pid=,user=,lstart=,args=
done | grep -Ev 'php-fpm|php-cgi|lsphp|apache2|httpd'
# PHP written into a web root since the leak
find /var/www -name '*.php' -newermt '2026-10-20' -ls
# There should be no PHP at all among WordPress uploads
find / -path '*/wp-content/uploads/*' -name '*.php*' 2>/dev/null
# Jobs and accounts added for the way back in
crontab -l -u www-data; ls -la /etc/cron.* /var/spool/cron 2>/dev/null
wp user list --role=administrator --fields=ID,user_login,user_registered
In process listings and logs, look out for these:
whoami,idoruname -arun as the web user/dev/tcp/,mkfifo,nc -eorfsockopenin a command linecurlorwgetfetching into/tmpor/dev/shm
If you find something, isolate the machine and keep the logs before you touch anything. Deleting a webshell tells you nothing about how it arrived or what else came with it.
6. When the dust settles
You now have something most agencies don't: a complete list of every PHP install you answer for. Keep it.
Then go down the list and ask a different question of each row: does this site need to run code on every visit? For most brochure sites, blogs and marketing pages, the honest answer is no. Every one of them you move to plain files is one fewer PHP install to round up the next time this happens. And it will happen again.
Updates
- 21 Oct, 09:45 UTC: first published, ahead of the advisory.
- 21 Oct, 11:05 UTC: Remi's repository will not ship the fix today. The expected fixed versions are noted. The two unofficial stopgaps are named, with what each breaks.