phphackfix
Remediation

Fix it: patch PHP, restart the workers, prove it

Fixed releases are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Everything below is a route to one of those, or to a vendor backport that contains the same fix.

Two rules that decide whether this works. One: a package upgrade does not fix a running process — restart Apache, PHP-FPM and any container. Two: the command-line PHP is not the web PHP. Verify through the SAPI that serves traffic.

1. Find every PHP on the box first

Most “we patched it” failures are a second runtime nobody remembered: a control-panel branch pinned per domain, an old container, or a vendor appliance.

# what is actually serving
ps -eo pid,user,lstart,args | grep -Ei '[p]hp-fpm|[a]pache2|[h]ttpd|[l]sphp|[f]rankenphp'

# installed versions
php -v; ls -1 /etc/php/ 2>/dev/null
dpkg -l 'php*' | awk '/^ii/{print $2, $3}'      # Debian/Ubuntu
rpm -qa 'php*' 'ea-php*' 'alt-php*' | sort       # RHEL family, cPanel, CloudLinux

2. Patch, by platform

Ubuntu and Debian

sudo apt update
sudo apt install --only-upgrade 'php8.*' 'libapache2-mod-php8.*'
sudo systemctl restart php8.3-fpm apache2

Fixed package versions verified 22 Oct 2026: Ubuntu 24.04 8.3.6-0ubuntu0.24.04.13, Ubuntu 22.04 8.1.2-1ubuntu2.28, Debian 12 8.2.35-1~deb12u1, Debian 13 8.4.27-1~deb13u1. Ubuntu ESM also published fixes for 14.04 through 20.04.

RHEL, AlmaLinux, Rocky, CloudLinux

sudo dnf clean all
sudo dnf update 'php*'
sudo systemctl restart php-fpm httpd

RHEL 9's php:8.2 module moved to 8.2.35-1.module+el9.8.0+25111+a1450321. Red Hat backports without changing the upstream number, so trust dnf updateinfo list --security, not php -v.

cPanel / WHM

sudo /scripts/upcp --security
/usr/local/cpanel/bin/rebuild_phpconf --current

sudo /scripts/restartsrv_httpd
sudo /scripts/restartsrv_apache_php_fpm

for p in /opt/cpanel/ea-php*/root/usr/bin/php; do "$p" -v | head -1; done

EA4 25.91 shipped ea-php82/83/84/85 at the fixed versions, and backported the fix to ea-php74/80/81. cPanel's internal PHP (used by hooks) is a separate runtime, updated in cPanel & WHM 136.0.50 — do not assume one covers the other.

Plesk

sudo plesk installer update
sudo plesk bin php_handler --list

Plesk ships its own PHP builds and every one of them is affected. Check each handler individually; a server can have eight, with domains pinned to the oldest.

CloudLinux, DirectAdmin, HestiaCP, aaPanel

sudo yum update 'alt-php*'                                  # CloudLinux Alt-PHP
cd /usr/local/directadmin/custombuild && ./build update && ./build php n   # DirectAdmin
v-update-sys-php                                            # HestiaCP

Docker and Kubernetes

docker pull php:8.3-fpm
docker image inspect php:8.3-fpm --format '{{index .RepoDigests 0}}'
docker compose up -d --force-recreate
kubectl rollout restart deployment/<name> -n <ns>

Pin by digest. A floating tag is whatever the registry had at pull time — which is how half a fleet ends up patched. Rebuild images that use FROM php:...; pulling a base image does nothing for a cached layer.

Windows / IIS

# replace the PHP tree IIS points at (check system.webServer/fastCgi), keep php.ini, then:
& $env:windir\system32\inetsrv\appcmd.exe recycle apppool /apppool.name:"DefaultAppPool"

PHP 8.1 and older

There is no upstream release. In order of preference: upgrade to 8.2+; apply a vendor backport (Ubuntu ESM, Debian ELTS, TuxCare ELS, cPanel ea-php, CloudLinux Alt-PHP); or build the PHP security team's minimal backport from the PHP-7.4-CVE-2026-109618-109619, PHP-8.0-… or PHP-8.1-… branches. Nothing exists for PHP 7.3 and below — isolate those hosts.

Ad slot — replace with your AdSense unit

3. Verify it actually took effect

Four checks, per server. “Patched” without the last two is how people end up wrong.

#ProofHow
1The serving SAPI reports a fixed versionDrop a temporary file with <?php echo PHP_VERSION, ' ', php_sapi_name(); in the web root, fetch it, delete it
2The package is the fixed releaseFull package version vs your vendor advisory — not just the first three numbers
3Every worker restarted after the installps -eo pid,lstart,args | grep php-fpm — start time must be later than the package install
4All installed branches fixedLoop ea-php*, /opt/alt/php*, pools, containers

Quick sanity check: if php -v says 8.3.36 but your site's headers or a phpinfo() page says 8.3.6, you have not patched the thing that matters. That specific mismatch is the single most common false “done” in this incident.

4. If you cannot patch today

PHP is explicit: there are no complete mitigations. These reduce exposure to known attack paths and buy time.

If the server was exposed before you patch, check for compromise first →

Need a second pair of eyes?

Multi-version panels, containers and staging copies are where this goes wrong. Verification evidence is the part that survives an audit.

Talk to someone