Skip to content

PHP2Shell: what the PHP flaws mean and how to fix them

Two critical PHP flaws, CVE-2026-109618 and CVE-2026-109619, were patched on 21 October 2026. What is affected, what to update, and what to check afterwards.

26 Oct 20267 min read

On 21 October 2026 the PHP project released fixes for two critical flaws in PHP itself, tracked as CVE-2026-109618 and CVE-2026-109619 and nicknamed PHP2Shell. Both are rated 9.2 out of 10 on the CVSS v4.0 scale, and both can let an attacker run code on a server without logging in. Because the flaws sit in the PHP engine, below WordPress, Drupal, Magento and every other PHP application, updating plugins or themes does not fix them. The PHP version on the server has to change.

This is a plain-English guide for people who run, or pay for, PHP websites: what happened, how worried to be, and what to do this week. It was written on 26 October 2026 from the sources listed at the end, and the story is still developing.

What happened#

  • 19 to 24 August: Wiz Research finds the first bug, confirms code execution without a login against Drupal and WordPress, and reports the issues to the PHP security team on 24 August.
  • 21 September: PHP acknowledges the reports and starts a coordinated fix.
  • 21 October: fixed releases and public disclosure. Cloudflare had switched on protective firewall rules for its Free and paid plans at 03:02 UTC, about nine hours earlier. The NSA, FBI and CISA urged organisations to fix the flaws.
  • 23 October: PHP published an informational advisory for a related issue, CVE-2026-115560, in the session upload-progress feature. It needs an unusual setup (described below) and is being handled in a regular release, not an emergency one.

Wiz says AI models played a major part in finding the bugs. The PHP team, Calif and OpenAI are credited with help on coordination and checking the patches.

What is actually wrong#

The PHP project describes the two flaws like this:

  • CVE-2026-109618, out-of-memory corruption. If PHP is interrupted by running out of memory while the data from a request is only half set up, the clean-up afterwards can treat invalid data as valid.
  • CVE-2026-109619, stale global state. Some per-request state can outlive the memory it points to, and a later request handled by the same worker can use it before it is reset.

Wiz, which found them, describes the underlying memory bugs in more detail: use-after-free bugs in PHP's upload-progress handling and in the code that records a fatal error's backtrace, a type confusion in OPcache, and a way to leak memory through a PHPSESSID cookie. Sansec reports that this leak can expose passwords, session tokens, API keys and TLS private keys, and that it works before application code runs. The sources differ on which detail belongs to which CVE number, so we do not match them up here.

What matters in practice is where the bugs live. They are in the engine, not in your application, so even a minimal site on an affected version is exposed, and a firewall that only inspects requests cannot always tell an attack from normal traffic.

How worried should you be#

Treat it as urgent, but know that the researchers disagree about how easy it is to exploit.

  • Wiz confirmed unauthenticated code execution against WordPress and Drupal.
  • Cloudflare reported attack traffic against its customers, including attackers changing their payloads to get past its rules.
  • Sansec reports that the public proof-of-concept code does not work against a default PHP installation, and that most of it needs the target application to have another flaw, such as local file inclusion. It concludes that mass exploitation is less likely than first feared.
  • The NSA, FBI and CISA urged organisations to fix the flaws. The FBI's post advised taking a system offline until it is mitigated if an immediate update is not possible. CISA said it had not seen exploitation at the time of its statement. No deadline was given.

Waiting to see which view turns out to be right is not a plan. The fix is an update and a restart.

Which PHP versions are affected#

Every PHP version back to 5.4 contains the vulnerable code. Only PHP 8.2 and later still receive official releases from the project.

PHP branchFixed inNotes
8.58.5.12Supported
8.48.4.27Supported
8.38.3.36Supported
8.28.2.35Supported until 31 December 2026
8.1, 8.0 and 7.4No new releaseThe PHP security team published minimal source patches, and some Linux distributions have backported them. Check your package's changelog (see below)
Older than 7.4NothingUnsupported and vulnerable

Moving a site written for PHP 5 or 7 to PHP 8 often means code changes, so that is a project in its own right. In the meantime, use a hosting provider or distribution that has backported the fix, apply the stopgaps below, and plan the move.

What to do this week#

  1. Find out what you run. List every place PHP serves traffic: your main site, a shop, staging copies, old microsites, and anything a hosting company or agency manages for you. Ask each provider for the exact PHP version in use and when PHP was last restarted.
  2. Update, then restart. Install a fixed release, or a package that carries the fix, and restart PHP-FPM (or Apache if you run mod_php) and the web server. Some package updates restart services for you and some do not, so check that the service's start time is after the update instead of assuming.
  3. If you cannot update yet, reduce your exposure. PHP's own advice is that these steps lower the risk but do not make a server safe, and that updating is the only safe choice. They are listed in the next section.
  4. Rotate secrets after patching. On any unpatched server that was reachable from the internet, treat anything a PHP worker could read as potentially exposed: database passwords, API keys, session secrets and TLS private keys. Rotate them once the server is patched, sign users out, and turn on multi-factor authentication where you can.
  5. Look for signs of abuse. Cloudflare says details leaked before the official release, so go back a few days before 21 October if your logs allow. Wiz lists these warning signs: unusual multipart requests followed by memory-limit errors, repeated HTTP 500 responses, unusually large or malformed PHPSESSID cookies, and PHP workers restarting for no clear reason. Also look for new administrator accounts, changed .php files (especially in upload folders), and outbound connections started by the web server's user.
  6. Plan to leave unsupported PHP. Every old version you keep running will be in this position again the next time a flaw like this appears.

Stopgaps if you cannot update yet#

PHP's announcement lists these partial mitigations:

  • Turn off upload progress in the server's configuration, then restart all workers. It must be set in php.ini, the FPM pool or server configuration, because ini_set() and .user.ini files are not enough.
  • Set a low post_max_size (PHP suggests 8M for a site with no uploads and 32M for one with uploads), keep upload_max_filesize below it, and enforce request-size limits at the web server or proxy.
  • On PHP 8.5, set fatal_error_backtraces=0 and restart the workers.
  • PHP also suggests removing the memory limit with php_admin_value so a request cannot reach it, but only together with a container or cgroup memory limit. Without one, a single request could use all of a server's memory.

The upload-progress setting looks like this:

ini
session.upload_progress.enabled = 0

A web application firewall helps as another layer. Cloudflare turned on managed rules by default for its Free and paid plans, and asks paid customers to confirm the rules are in block mode. It says they are a layer of defence, not a replacement for patching.

About CVE-2026-115560: PHP describes it as needing an unusual setup, an application that switches session.serialize_handler at runtime before starting a session while upload progress is still on. Until the next regular release, PHP suggests turning upload progress off, which the stopgap above already does. Cloudflare notes that its rule covers PHP's default upload-progress field name, so a site that renamed it is not covered by that rule.

Checking whether your packages have the fix#

On a server that uses distribution packages, the changelog shows whether the fix has been included, even when the version number looks old:

sh
# Debian and Ubuntu (change 8.1 to your PHP version)
zgrep CVE-2026-109618 /usr/share/doc/php8.1-common/changelog.Debian.gz

# Red Hat, AlmaLinux, Rocky and Fedora
rpm -q --changelog php-common | grep CVE-2026-109618

Need a hand?#

If you run PHP sites and want a second pair of eyes on your exposure, or help moving off an unsupported version, tell us what you run.

Talk to us

Sources#

This guide is a summary of the sources below. We have not tested exploitation ourselves, and the details may change as the PHP project and researchers publish more.

Get new posts by email

New posts by email. No spam. See the privacy policy.

Keep reading

Have a process that eats hours? Tell us about it.

A short call is enough to tell you whether an agent is the right answer, and what it would take.