If you run a PHP site and saw the PHP2Shell headlines, the short version is this: check your PHP version, update to the fixed release for your branch, and restart your PHP workers. That's most of the job. The longer version matters too, because the version check is easy to get wrong and restarting workers is the step people skip. This article walks through what to do today, what the fixed versions are, and what to look for if you think you were hit.

PHP2Shell is the nickname for two vulnerabilities, CVE-2026-109618 and CVE-2026-109619, both allowing unauthenticated remote code execution in PHP. Fixes shipped on 21 October 2026. PHP runs roughly 70% of websites (W3Techs puts it at 69.3%), so almost every WordPress, WooCommerce, Drupal, Laravel and Magento site is in scope until proven patched.

What to do today

Start by finding out which PHP version you're running. On a server you control:

php -v
# and, because the CLI can differ from what serves web requests:
php-fpm -v

If you're on a shared or managed host, the PHP version is usually in your control panel, or you can drop a one-line phpinfo() script (and delete it after). Once you know the version, compare it to the fixed releases below.

From there, the job comes down to two actions and a fallback. Updating to the fixed release for your branch is the only complete fix, per Tenable, Wiz and CISA -- the patch fixes the issue at its core and, as Wiz puts it, eliminates all variants. The step people miss is restarting your PHP workers afterward: packages on disk don't patch running workers, and Google Cloud and Tenable both stress that you have to restart php-fpm, apache2/httpd, frankenphp or lsws once the update is in place. An updated package with a stale worker is still vulnerable. And if you can't patch at all, or you're on PHP 8.1 or older, CISA's guidance is blunt: take the PHP system offline. More on interim settings below if offline isn't an option.

Fixed versions by branch

The table below lists the releases that contain the fix, per CISA, Tenable and Google Cloud:

PHP branch Fixed version Notes
8.5 8.5.12 Carries a SimpleXML crash regression (php-src #24488)
8.4 8.4.27 Same SimpleXML crash regression
8.3 8.3.36
8.2 8.2.35
7.4 to 8.1 No official release Minimal source backports only
5.4 to 7.3 End of life No fix from the PHP project

Two things are worth flagging here. The first is that 8.4.27 and 8.5.12 ship with a SimpleXML crash regression that came in with a separate GC fix -- patch anyway, but watch for SimpleXML-related crashes if your app uses it.

The second is that the version number isn't always the whole story. Distributions backport the fix without bumping the major version, so you might see 8.1.34 that is patched because the package release underneath changed. Sansec lists deb.sury.org, Ubuntu, Remi, AlmaLinux, CloudLinux, TuxCare and ZendPHP as sources of backports. To confirm a Debian-style backport actually contains the fix:

zgrep CVE-2026-109618 /usr/share/doc/php8.1-common/changelog.Debian.gz

If that returns nothing, the running version number alone doesn't mean you're safe -- and note that the official PHP Docker image has no fix for 8.1 or older.

What to do by hosting type

The right move depends on how your site is hosted. The vulnerable SAPIs are PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed, and PHP's own advisory rates mod_php the highest risk, per CISA and Tenable.

Hosting type What to do
Shared or managed host Ask your host directly whether they've patched and restarted workers. Don't assume. If they can't confirm, treat the site as exposed.
VPS or dedicated Run the version check, update via your package manager to the fixed release or a confirmed backport, then restart php-fpm/apache2/httpd/lsws. Verify backports with zgrep.
Docker Pull an updated base image for 8.2 through 8.5 and rebuild. There's no official image fix for 8.1 or older, so plan a branch upgrade or take it offline.
End-of-life PHP (5.4 to 7.3) No fix from the PHP project. Take the PHP system offline, or upgrade to a supported, patched branch.

If you can't patch right now

If an update isn't possible today and you can't take the site offline, there are interim php.ini settings. These are stopgaps, not fixes. Per Tenable, Sansec and Google Cloud:

; put these in the main php.ini, NOT .htaccess
memory_limit = -1
session.upload_progress.enabled = 0
; on PHP 8.5 only:
fatal_error_backtraces = 0

A few warnings come straight from the sources. Disabling upload progress on its own isn't enough, and Sansec and Google Cloud also list pm.max_requests = 1, which makes every worker recycle after a single request. These settings belong in the main php.ini, not .htaccess, and whatever you change, restart the workers afterward. Blocking all multipart requests at the edge does break file uploads, so treat that as a last resort.

Cloudflare published WAF rules across all tiers, including free, but its CTO, Dane Knecht, called them a "STOPGAP only" (quoted by Tenable). A WAF buys time, but it doesn't close the hole.

Why it's serious

Two things make PHP2Shell serious, and both are specific rather than theoretical.

The first is unauthenticated remote code execution -- no login needed. As Wiz put it, even a simple "Hello World" application on an affected PHP version can be vulnerable. Wiz demonstrated pre-auth RCE on the latest WordPress, Drupal and Joomla images, and Calif's list of affected software includes Magento 2.4.9, WordPress, Drupal, Joomla, Laravel 13.11, Symfony 8.1, phpMyAdmin, Nextcloud and WHMCS. Stores can be hit even when their own code is clean, because the flaw is in PHP itself, not in your plugins.

Both bugs are use-after-free issues. An out-of-memory fatal error interrupts PHP before it cleans up, and a later request or a reused worker then treats freed memory as live data. CVE-2026-109618 is an upload-progress unserializer use-after-free (Tenable's shorthand: "OOM Corruption"), while CVE-2026-109619 is a fatal-error backtrace use-after-free plus an OPcache type confusion ("Stale Global State"). Both rate CVSS v4.0 9.2; an earlier 10.0 figure circulated before release but was incorrect per the PHP Foundation.

The second reason is memory disclosure. Leaked memory can come back inside a PHPSESSID response cookie, and that memory can contain passwords, session tokens, API keys and TLS private keys -- this happens even if your app never calls session_start(). Sources disagree on which of the two CVEs carries the disclosure, but the risk is the same either way: secrets walking out the door in a cookie.

The vulnerable code dates back to PHP 5.4.0, released in 2012, so every version from 5.4 through 8.5.11 is affected -- a lot of history to patch across.

Why mass exploitation was slower than feared

This is where the hype deserves a cold shower. The CVSS score is high and the RCE is real, but the attack isn't a point-and-click affair against a default install.

Sansec spelled out the preconditions: an attack needs specific knowledge of the target server and specific conditions on it. Public proof-of-concept exploits don't work on a default install, most need a local file inclusion bug already present, and all known triggers are multipart/form-data requests -- a combination that narrows the field considerably compared to the worst-case reading of the headlines.

That said, working exploits exist: Trail of Bits confirmed them on pre-patch 8.2 through 8.5 against MediaWiki, Symfony, Laravel and phpBB. The attack attempts started early too -- Cloudflare saw activity at 07:43 UTC on 21 October, before the release even went out, and Amazon reported an attempt on 17 October along with broader exploitation attempts. If you're reviewing logs, Tenable recommends starting from 17 October.

The discovery story is part of why the window was tight. Ryan Austin of Calif found RCE paths on 1 August 2026 and reported the first bug on 11 August; Wiz reported on 24 August. Details leaked on 20 October, the release was moved up a day, and fixes shipped at 14:00 UTC on 21 October. Wiz noted that a single researcher completed in a week what previously would have taken a top research team months, with help from Wiz Atlas, Gemini 4 Argon and GPT-5.6 Sol -- OpenAI is credited as well. The point either way: faster discovery cuts both ways, and the leak compressed everyone's response time.

Other organizations treated it with similar caution. On 21 October, several Dutch sites went offline as a precaution, including Tweakers, the House of Representatives, NCSC and Security.NL. CISA added both CVEs to its Known Exploited Vulnerabilities catalog on 26 October, with a federal patch deadline of 29 October.

Exposure is wide: Silas Cutler counted more than 1.3 million exposed hosts, and Henk Poley found more than 1.9 million PHP hosts on Shodan. "Slower than feared" does not mean "ignore it."

If you think you were hit

Here's what to look for, drawn from CISA, Wiz and Google Cloud: PHP workers spawning sh, curl or wget (workers shouldn't be shelling out), PHPSESSID cookies larger than 256 bytes (an oversized session cookie is a disclosure tell), multipart requests followed by memory errors or 500 responses, and SIGSEGV respawns that show up as exit code 139.

One hard truth: some exploit chains leave no crashes and nothing in error.log, so absence of errors is not proof of safety. CISA published a SIGMA rule you can feed into your detection tooling.

If a host is under suspicion, capture worker memory before you restart it -- restarting clears the evidence, so preserve first and remediate second.

If you find signs of compromise on a WordPress site, don't just patch and move on; an attacker with RCE may have left persistence behind. Our step-by-step hacked WordPress recovery guide walks through cleanup properly.

Shrinking your PHP attack surface long term

Patch first. Everything above comes before anything in this section. But once the fire's out, it's worth asking a slower question: how much PHP needs to be reachable from the public internet at all?

PHP2Shell is a reminder that a flaw in the runtime itself can expose a site even when your own code is clean. The more of your public surface that's served as static files or from a headless front end, the fewer requests ever reach a PHP process. A static or headless front end built with Astro or Next.js can serve pages, marketing content and product catalogs without a live PHP interpreter answering every visitor, while PHP stays behind the scenes for the pieces that genuinely need it.

Be clear-eyed about this, though. Static and headless front ends are not immune to everything. They have their own build pipelines, dependencies and APIs to secure, and any PHP backend you keep still needs patching. What a smaller PHP surface buys you is fewer PHP processes exposed to the next unauthenticated-RCE headline, not invulnerability. It's a reduction in blast radius, not a magic shield.

If you're weighing whether a headless front end makes sense for your WordPress, WooCommerce or Magento setup, get in touch and we'll talk through what's realistic for your stack.

FAQ

What PHP version do I need to be on to be safe?

Update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 depending on your branch, per CISA, Tenable and Google Cloud. If you're on a distribution that backports fixes, the version number may stay the same (like 8.1.34) with a new package release, so verify the changelog. Versions 5.4 through 8.5.11 are all affected.

I updated the package but didn't restart anything. Am I protected?

No. Packages on disk don't patch running workers. You must restart php-fpm, apache2/httpd, frankenphp or lsws after updating, as Google Cloud and Tenable both stress. An updated package with a stale worker is still exploitable until that worker recycles.

I'm on PHP 8.1 or older. What now?

There's no official fix for 7.4 through 8.1, only minimal source backports, and 5.4 through 7.3 are end of life with no project fix at all. CISA says to take the PHP system offline if you can't patch. Your realistic path is a distro backport (verify it) or an upgrade to a supported, patched branch.

Can a WAF protect me instead of patching?

No. Cloudflare published WAF rules across all tiers including free, but Cloudflare's own CTO called them a stopgap only. Updating is the single complete fix, per Tenable and Wiz. A WAF buys you time to patch; it doesn't close the vulnerability.

Is my Magento store affected if my own code is clean?

Yes, potentially. The flaw is in PHP itself, not in your plugins or custom code. Calif lists Magento 2.4.9 among affected software, and Sansec notes stores can be affected even when their own code is clean. Patch the PHP runtime regardless of how tidy your application is.

Why did mass exploitation turn out slower than the headlines suggested?

An attack needs specific knowledge of the target and specific conditions, per Sansec. Public proof-of-concept exploits don't work on a default install, most need a local file inclusion bug, and all known triggers are multipart/form-data requests. That narrows the field, though Trail of Bits confirmed working exploits on pre-patch 8.2 through 8.5.

How do I know if I was already compromised?

Look for PHP workers spawning sh, curl or wget, PHPSESSID cookies over 256 bytes, and multipart requests followed by memory errors or 500s. Some chains leave no crashes or error.log entries at all. Capture worker memory before restarting any suspect host, and use the SIGMA rule CISA published. Review logs from 17 October onward.

Does moving to a static or headless front end make this go away?

It shrinks the surface, not the risk entirely. Serving more pages as static files or from a headless front end with Astro or Next.js means fewer requests reach a live PHP process. But static sites aren't immune to everything, and any PHP backend you keep still needs patching. Think smaller blast radius, not invulnerability.