# PHP2Shell (CVE-2026-109618, CVE-2026-109619): what to patch and how to mitigate

> PHP2Shell is a pair of critical unauthenticated RCE flaws in the PHP engine. Fixed versions, interim mitigations from the advisories, and detection steps.

- Published: 2026-10-21
- Author: Enforster AI (https://enforster.ai)
- Category: Security Operations
- Tags: Security Operations, Secure Coding, Engineering, Risk Management
- Canonical URL: https://blog.enforster.ai/php2shell-cve-2026-109618-cve-2026-109619

## Key takeaways

- PHP2Shell is two critical PHP engine vulnerabilities, CVE-2026-109618 and CVE-2026-109619, each rated CVSS v4.0 9.2, that can allow unauthenticated remote code execution as the web worker account.
- The fixed releases are PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35, published on October 21, 2026; PHP states that updating is the only complete mitigation.
- Because the flaws are in the PHP engine, a site can be vulnerable even when its own application code is secure, and PHP workers must be restarted after patching to load the fix.
- For unpatched PHP 8.5, the advisories list setting fatal_error_backtraces=0 and session.upload_progress.enabled=0 as partial mitigations that cover specific known cases only.
- A PHP worker process such as php-fpm or apache2 spawning a shell, interpreter, or download tool is a high-signal indicator of exploitation.

---

PHP2Shell is the name for two critical vulnerabilities in the PHP engine itself, CVE-2026-109618 and CVE-2026-109619, that can let an unauthenticated attacker run code on a web server. They affect ordinary PHP deployments regardless of the application running on top, so WordPress, Drupal, and custom code are exposed alike. Upgrade to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35 (or your distribution's patched package) and restart every PHP worker. PHP's own advisory says updating is the only complete mitigation.

This guide covers what the bugs are, how to patch, what to do for servers you cannot patch today, and what exploitation looks like. It reflects the advisories as of October 21, 2026.

## What are CVE-2026-109618 and CVE-2026-109619?

Both are memory-safety bugs in how PHP recovers from fatal errors, especially out-of-memory errors. The PHP security team rates each one critical, CVSS v4.0 9.2. The CVSS vector marks attack complexity as high, because reliable exploitation depends on build, configuration, and memory layout; the impact is still full compromise of the worker.

- **CVE-2026-109618, RCE via out-of-memory corruption.** PHP uses `longjmp()` to bail out of an out-of-memory error. Per the [PHP advisory GHSA-w8hw-w9fx-j79w](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w), some request memory is reachable before it is fully initialized, so if an allocation fails at that moment, request shutdown can act on invalid memory. Crafted multipart requests can trigger it. The advisory confirms unauthenticated RCE against Apache mod_php with default input and memory limits. For PHP-FPM, source analysis supports susceptibility but no complete exploit had been shown; FrankenPHP and LSAPI are suspected but unvalidated.
- **CVE-2026-109619, RCE via stale global state.** Per [GHSA-6wmf-4rv5-p3rp](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp), persistent workers can keep global error, session, object, and extension state that points into memory freed at the end of a previous request. A later request handled by the same worker can then use that stale pointer, giving heap use-after-free, memory disclosure, and code execution. Confirmed cases include PHP 8.5 with `fatal_error_backtraces` enabled (the basis of the confirmed mod_php RCE) and session upload progress, validated against both mod_php and FPM.

[Wiz Research](https://wiz.io/blog/php2shell-php-rce), which reported the bugs together with other researchers, says it found four underlying bugs grouped under these two CVEs, demonstrated unauthenticated RCE against current WordPress, Drupal, and Joomla container images, and believes every PHP version released in the last decade contains at least one of them. Wiz also says AI models assisted with discovery, exploit development, and patch validation.

> **Your code being clean does not help:**
>
> The vulnerable code runs before or around your application, during request setup and teardown. A minimal application on an affected PHP build can be exploitable, so do not deprioritize servers because their application passed a code review.

## Why is this being treated as urgent?

The details leaked before the planned disclosure. [Huntress](https://www.huntress.com/blog/php2shell-leaked-critical-php-vulnerabilities) reports that a post describing the flaws appeared publicly on October 20 and was taken down after screenshots had spread. PHP then announced an accelerated security release for October 21 at 14:00 UTC.

As of Huntress's October 21 update, it had not seen in-the-wild exploitation across its customer base, though other researchers reported attacks emerging, and it said an exploit exists for mod_php. Treat the exploitation status as fluid and assume working exploits will become widely available.

## Which versions fix PHP2Shell?

The PHP project released these fixed versions on October 21, 2026, according to the [php.net release announcements](https://www.php.net/):

| Branch | Fixed version | Note |
| --- | --- | --- |
| 8.5 | 8.5.12 | |
| 8.4 | 8.4.27 | |
| 8.3 | 8.3.36 | |
| 8.2 | 8.2.35 | Branch reaches end of life on 31 December 2026 |

The 8.6.0 RC4 test release also contains the fixes but is not for production. Huntress reports minimal source backports for 7.4, 8.0, and 8.1, and that older branches may get no official patch.

Most Linux servers get PHP from the distribution, so the version number may not match the table even when the fix is present. Use your distribution's advisory. [Ubuntu](https://ubuntu.com/blog/php2shell-vulnerability-fixes-available), for example, lists patched packages from 14.04 through 26.10, with releases older than 22.04 covered through Ubuntu Pro ESM.

## How do I patch and verify?

Patch internet-facing servers first, then everything else that runs PHP, including PHP bundled inside control panels, appliances, and vendor software. Then restart: a patched package does nothing until the running workers are replaced.

On Ubuntu or Debian-style systems:

```bash
# See which PHP packages are installed
apt list '?installed ?name(^php[0-9.]+$)'

# Upgrade PHP packages only, then restart whatever runs PHP
sudo apt update && sudo apt install --only-upgrade '?name(^php[0-9.]+$)'
sudo systemctl restart apache2          # mod_php
sudo systemctl restart 'php*-fpm'       # PHP-FPM pools

# Confirm the version the CLI and the web SAPI actually run
php -v
```

Check the web SAPI as well as the CLI. They can come from different packages, and container images pin their own PHP version, so rebuild images from a patched base rather than patching running containers.

## What can I do if I cannot patch today?

There is no complete workaround. The advisories list partial mitigations that close specific known paths. Apply them only as a stopgap, set them administratively so applications cannot override them, and restart every worker afterwards.

```ini
; php.ini or pool config, then restart all workers
fatal_error_backtraces = 0          ; PHP 8.5: closes the confirmed backtrace case
session.upload_progress.enabled = 0 ; closes the session upload-progress case
```

The CVE-2026-109619 advisory also suggests eliminating reachable fatal errors and timeouts on attacker-reachable requests, removing INI diagnostics at startup, and considering `pm.max_requests=1` for FPM, which recycles a worker after every request at a real performance cost. For CVE-2026-109618, the advisory describes enforcing `memory_limit=-1` as the primary configuration mitigation, while noting it is incomplete and shifts memory exhaustion elsewhere. It also recommends capping decoded request size at the frontend, keeping `post_max_size` conservative, and blocking multipart requests entirely if the application does not accept file uploads or multipart forms.

> **Do not use RLIMIT_AS as a fix:**
>
> The CVE-2026-109618 advisory warns against `RLIMIT_AS` and `RLIMIT_DATA`: they make `mmap()` fail, which triggers the vulnerable out-of-memory path. Container memory limits are not a complete mitigation either.

For end-of-life PHP that will not get a patch, Huntress suggests taking the system offline or placing it behind a VPN or WAF until it can be upgraded.

## How do I detect exploitation attempts?

Look at what PHP workers do, not only at requests. Huntress recommends alerting when a PHP worker process (`php-fpm`, `php-cgi`, `httpd`, `apache2`) spawns a shell, a scripting interpreter such as Python or Perl, or a download or network tool such as `curl`, `wget`, or `nc`, and on command lines containing `/dev/tcp/`, `fsockopen`, or `mkfifo`. Reconnaissance commands like `id`, `whoami`, or `uname -a` run by the web server user are also strong signals.

On the request side, Wiz suggests watching for unusual multipart requests followed by memory-limit errors or bursts of HTTP 500 responses, unusually large or malformed `PHPSESSID` cookies, and unexplained worker churn.

If you suspect compromise, isolate the server, preserve web server and PHP logs, and check for web shells, new files in the web root, new cron jobs, and new accounts. Rotate any credentials the PHP application could read, such as database passwords and API keys in its configuration.

## What should teams take from PHP2Shell?

Runtime vulnerabilities bypass application security entirely, so patch speed depends on knowing where every runtime lives. If answering "where do we run PHP?" took more than a few minutes this week, that inventory is the gap to close.

PHP2Shell landed on the same day as another incident with a similar lesson about trusting the layer beneath your code: the [LiteLLM 1.107.0 supply chain compromise](https://blog.enforster.ai/litellm-1-107-0-supply-chain-compromise), where the poisoned component was a dependency rather than the runtime.
