PHP2Shell: What the Critical PHP Vulnerabilities Mean for WordPress Sites

Quick Summary

  • PHP2Shell is two critical PHP vulnerabilities (CVE-2026-109618 and CVE-2026-109619) that can let an attacker run code without logging in; PHP fixed them in 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on 21 October 2026.
  • The flaws are in PHP itself, so WordPress, plugin and theme updates cannot fix them: your hosting company or server administrator has to install the patched PHP and restart it.
  • Until then, turning off session upload progress and using a web application firewall reduce the risk; after patching, check for unknown admin users, changed files and PHP files in uploads.

On 21 October 2026, the PHP project shipped emergency security releases for two critical vulnerabilities, nicknamed PHP2Shell. They can let an attacker run code on a server without logging in, and attacks started the same day. Because WordPress runs on PHP, every WordPress site needs a PHP update, and the fix doesn’t come from WordPress. Here’s what happened, why a fully updated WordPress site can still be exposed, and exactly what to do.

The short version: make sure your server runs PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or a patched package from your hosting company or Linux distribution), and that PHP was restarted afterwards. WordPress, plugin and theme updates can’t fix this for you.

What happened with PHP2Shell

  • 20 October: details of the vulnerabilities leaked on social media before the planned disclosure date. The same day, the PHP project announced an emergency release for the next afternoon.
  • 21 October: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 were released, fixing CVE-2026-109618 and CVE-2026-109619. Both are rated 9.2 out of 10 (CVSS v4.0, critical).
  • From 21 October: security firm watchTowr reported exploitation in the wild through its honeypots, and Cloudflare reported attack traffic aimed at its customers, with attackers changing their payloads to get around the filters.
  • 23 October: PHP published a follow-up advisory, CVE-2026-115560, about a related issue that also affects the patched releases (more on that below).

Palo Alto Networks’ Unit 42 counted over 22.6 million internet-facing systems that were potentially vulnerable when it published its brief.

The two vulnerabilities in plain English

Both bugs are in PHP itself, not in WordPress or any plugin. PHP’s advisory describes them as:

  • CVE-2026-109618, “RCE via OOM corruption”: when PHP runs out of memory at the wrong moment while reading a request, it can be left working with data that was only half set up. An attacker can trigger that on purpose and turn it into code execution.
  • CVE-2026-109619, “RCE via stale global state”: after certain fatal errors, PHP can keep pointers to memory that has already been freed. A later request can make use of that leftover state to run code.

“RCE” means remote code execution: an attacker can run their own code on your server. On a WordPress site that means full control: your files, your database, your customers’ details and anything else on the same server.

Why a fully updated WordPress site is still at risk

The vulnerable code runs before WordPress does. For Apache’s mod_php, PHP’s advisory describes a demonstrated exploit where a request from someone who isn’t logged in triggers the attack before any application code runs. That has three consequences:

  • WordPress auto-updates don’t help. They update WordPress, plugins and themes, not the PHP program your server uses to run them.
  • Security plugins can’t stop it. A plugin only runs once WordPress has loaded, which is too late for this attack path.
  • It’s not only WordPress. WooCommerce stores, Laravel apps, Drupal, Magento and any other PHP site are affected in the same way.

According to PHP’s advisory, every PHP installation that serves web requests is in scope: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The PHP team considers the risk highest for mod_php. Cloudflare says the original vulnerabilities affect every version from PHP 5.4 onwards.

What to do now

1. Check which PHP version your site actually runs

In WordPress, go to Tools → Site Health → Info → Server and look at PHP version. That’s the version serving your website. The php -v command on a server reports the command-line version, which can be different.

A version number on its own doesn’t always tell the whole story. Linux distributions such as Debian, Ubuntu and Red Hat often apply security fixes to their own PHP packages without changing the main version number, so an older-looking version may already be patched. Ask whoever maintains the server.

2. On managed or shared hosting: ask your host

If a hosting company runs your server, they install PHP updates, not you. Ask them two questions: “Is the patched PHP for CVE-2026-109618 and CVE-2026-109619 installed on my server?” and “Has PHP been restarted since?” Get a yes to both.

3. On your own server or VPS: update and restart PHP

Install the updated PHP packages from your distribution or PHP repository, then restart every PHP process. On Debian or Ubuntu with PHP-FPM, for example:

Shell
sudo apt update
apt policy php8.3-fpm            # shows the installed and the available version
sudo apt upgrade                 # installs the patched PHP packages
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2   # only if you use Apache with mod_php

On AlmaLinux, Rocky Linux or RHEL with the Remi packages, update with sudo dnf upgrade 'php*' and restart php-fpm. Replace 8.3 with your own version. If you install PHP from the Sury repository on Debian, my guide on installing PHP on Debian covers where the packages come from.

The restart matters. Running PHP processes keep the old, vulnerable code in memory until they restart.

4. If you can’t update today: reduce the risk

PHP is clear that only an update fixes this, and that no configuration change is a complete fix. In the meantime, a few measures make specific attack paths harder:

  • Turn off session upload progress, then restart PHP. Set it in php.ini or your PHP-FPM pool, not with ini_set() or a .user.ini file, because those apply too late. WordPress itself doesn’t rely on this feature.
  • Put the site behind a web application firewall. Cloudflare deployed rules for these vulnerabilities to every plan, including the free one, on 21 October.
  • If a server can’t be patched yet, restrict who can reach it, for example by limiting it to known IP addresses or taking it offline for a few hours.
Code
; php.ini (or the PHP-FPM pool configuration), then restart PHP
session.upload_progress.enabled = 0

PHP’s advisory lists further partial measures for the out-of-memory bug, such as a lower post_max_size and request limits at the web server. If you run your own servers, read the full advisory before changing them.

5. After patching: check that nobody got in

Attacks started before many servers were patched, so it’s worth a quick check after you update. With WP-CLI:

Shell
wp core verify-checksums                 # compares WordPress core files with the official release
wp plugin verify-checksums --all         # does the same for plugins from WordPress.org
wp user list --role=administrator        # any admin accounts you don't recognise?
find wp-content/uploads -name '*.php'    # uploads should contain no PHP files

Also look for files changed recently that you didn’t change, unfamiliar scheduled tasks, and unexpected outgoing connections. If anything looks wrong, restore a clean backup taken before 20 October, change every password and secret key, and patch PHP before you bring the site back.

The follow-up issue: CVE-2026-115560

On 23 October, PHP published an informational advisory about a related problem with session upload progress. It also affects the patched releases and will be fixed in PHP’s next regular release, not in an emergency one.

PHP calls it an unlikely way in. It needs a specific set-up: an application that sets session.serialize_handler to php_binary or php_serialize and then switches it to php while running, before starting the session, with upload progress still turned on. Most WordPress sites won’t match that, but the protection is the same setting as above: session.upload_progress.enabled = 0. If you already set it, keep it in place.

Old PHP versions get no fix

PHP 8.1 and older no longer receive releases from the PHP project. The advisory links to minimal source patches for PHP 7.4, 8.0 and 8.1, and some Linux distributions and long-term support vendors ship their own fixed packages. For most site owners, the realistic fix is to move to a supported version.

PHP 8.2 itself reaches end of life on 31 December 2026, so a site that has to move anyway should go to PHP 8.3 or newer. Test the site on the new version first; older themes and plugins are the usual source of problems after a PHP upgrade.

The takeaway for WordPress owners

Keeping WordPress up to date was never the whole job. The PHP version, the web server and the operating system underneath it need updates too, and on most sites nobody watches them. If you aren’t sure who looks after your server’s PHP, now is a good time to find out. If you’d like a hand with checks, updates or a PHP upgrade on a WordPress site, that’s part of my WordPress development and maintenance work.

Sources

Share on X (opens in a new tab) Share on LinkedIn (opens in a new tab) Share on Facebook (opens in a new tab)

ChatGPT (opens in a new tab) Claude (opens in a new tab) Gemini (opens in a new tab) Perplexity (opens in a new tab) Grok (opens in a new tab)

More Insights

See More