Codebusters

PHP2Shell Fix on Plesk: How to Check Every Site Is Really Patched

Wednesday 21 October 2026

PHP released fixes today for two critical bugs, both scored 9.2 out of 10, and Cloudflare is already reporting early attacks. They’ve been nicknamed PHP2Shell, which doesn’t sound good. I run 13 sites on one Plesk server, so the question wasn’t “do I need to patch” (obviously) but “how do I PROVE every single site is running the fixed version?”

Written on Wednesday 21 October 2026, the day of the release. I’ll add an update note below if anything changes.

I installed the Plesk update, then checked three different ways. Here they are, with the real output from my server.

What was fixed

Two bugs, CVE-2026-109618 and CVE-2026-109619, both CVSS 9.2. According to Sansec’s write-up an unauthenticated attacker can trigger them with multipart/form-data requests (the file upload kind), and they affect PHP from 5.4.0 onwards. The fixed versions are 8.5.12, 8.4.27, 8.3.36 and 8.2.35, and the php.net changelog lists the fix in 8.4.27 and 8.5.12. Mine are 8.4 and 8.2, so 8.4.27 and 8.2.35 are the numbers I’m looking for.

PHP 8.1 and older get NO fix. If that’s you, patching isn’t an option and you need to move up a branch instead.

Most of my sites are WordPress, but updating WordPress or your plugins won’t help with this one because the hole is in PHP itself. Tenable’s FAQ quotes a PHP core developer saying the only real mitigation is patching PHP.

Step 1: install the update

Plesk had new PHP 8.4 and 8.2 packages available soon after the release and I installed them over SSH rather than clicking through the panel. That’s the easy bit. The bit that matters is proving it worked, because Plesk happily runs several PHP versions side by side and every site picks its own.

Check 1: which PHP binaries are on the server?

Over SSH, start by looking at what Plesk has installed:

ls /opt/plesk/php/

Mine shows just 8.2 and 8.4, so those were the two to check. Ask each one for its version:

/opt/plesk/php/8.4/bin/php -v | head -1
/opt/plesk/php/8.2/bin/php -v | head -1

And I got:

PHP 8.4.27 (cli) (built: Oct 21 2026 08:34:02) (NTS)
PHP 8.2.35 (cli) (built: Oct 21 2026 07:37:27) (NTS)

Both fixed, both built today. Here’s the trap though – plain php -v on my server runs /usr/local/bin/php, which says 8.2.35, but most of my sites run 8.4. The command line PHP and the PHP serving your website are different programs, so php -v on its own tells you almost nothing about your sites!

Check 2: has PHP-FPM actually restarted?

New files on disk are no use if the old process is still sitting in memory. Each Plesk PHP version has its own FPM master process, so I looked at when they started:

ps -eo pid,lstart,cmd | grep "php-fpm: master" | grep -v grep
100747 Wed Oct 21 15:00:44 2026 php-fpm: master process (/opt/plesk/php/8.4/etc/php-fpm.conf)
100755 Wed Oct 21 15:00:44 2026 php-fpm: master process (/opt/plesk/php/8.2/etc/php-fpm.conf)

Both started at 15:00:44 today. I then compared that with the timestamp on the FPM programs themselves:

stat -c '%y %n' /opt/plesk/php/8.4/sbin/php-fpm /opt/plesk/php/8.2/sbin/php-fpm

Those say 09:34 and 08:37 this morning, so the running processes started well after the files changed. Nothing left over from yesterday.

Check 3: ask the live sites

This is the one that settles it, because it asks the sites themselves. By default PHP adds an X-Powered-By header to every page it generates, so a quick curl shows you the version that actually served the request:

for d in example.com example.org example.net; do
  echo -n "$d "
  curl -s -I "https://$d/" | grep -i '^x-powered-by: PHP'
done

(That header is also how anyone else can see your version. There’s an expose_php setting if you’d rather hide it, but I haven’t changed mine.)

I ran it over all 13 of my sites. Two of them, codebusters.uk and linkworthy.uk, looked like this:

codebusters.uk x-powered-by: PHP/8.4.27
linkworthy.uk x-powered-by: PHP/8.4.27

Across the whole lot, 10 said PHP/8.4.27, 1 said PHP/8.2.35 and 2 said nothing at all. I thought that last bit was a problem until I looked – those two are plain HTML sites with a single index.html each, so nginx hands the file over and PHP never gets involved. No PHP, no header, nothing to patch.

So that’s 11 out of 11 PHP sites on the fixed versions, and 2 that never needed it. Not bad for a Wednesday afternoon!