Resources / Security advisory Critical · Patch now

PHP2Shell: critical unauthenticated RCE in PHP, patched 21 October 2026

By the Fixed.net engineering team · 22nd October 2026 · CVE-2026-109618 · CVE-2026-109619

Two related critical vulnerabilities in the PHP core, collectively called PHP2Shell, allow unauthenticated remote code execution (RCE) on web-facing PHP installations. They were disclosed and patched on 21 October 2026, following an advance notice and leak on 20 October.

Both carry a CVSS v4.0 score of 9.2 and affect memory management and request/error handling paths that nearly every request touches.

CVSS v4.0 9.2
Attack Unauthenticated RCE
Affected PHP 5.x to early 8.5.x
Patched 21 Oct 2026
What Fixed.net has done

We mitigated before the patch, then patched as soon as it shipped

20 OCT 2026 Done
Interim mitigation applied

As soon as PHP issued its advance notice, we put the PHP project's recommended interim mitigations in place across the servers we manage, to protect sites until an official fix was available.

21 OCT 2026 Done
Official fix implemented

When PHP published the fixed releases, we updated to the patched versions and restarted all PHP workers so the fix is live.

Hosted somewhere else? Follow the steps below. For next time, host your site with us on a maintenance plan and we'll handle updates like this for you.

Overview and impact

Who is affected

All PHP installations serving web requests, including:

Apache with mod_php · highest risk PHP-FPM php-cgi FrankenPHP LiteSpeed Others

The risk is highest on mod_php, where a demonstrated unauthenticated exploit can trigger before any application code runs, so framework middleware, input validation and similar protections never get a chance to act.

What an attacker can do

Unauthenticated RCE as the web worker account. This can lead to full server compromise, data theft (including credentials or tokens held in process memory) or denial of service. PHP underpins a very large share of the public web, commonly cited at around 70% or more of sites with an identifiable back end, and that includes every WordPress site.

Vulnerable and fixed versions

Effectively PHP 5.x through early 8.5.x is vulnerable, with reports extending back to around 5.4. The supported branches (8.2 to 8.5) received full fixes on 21 October 2026:

Branch Fixed in Status
PHP 8.58.5.12Supported
PHP 8.48.4.27Supported
PHP 8.38.3.36Supported
PHP 8.28.2.35Security support ends 31 December 2026
PHP 8.1 and olderNo official releaseEnd of life. Minimal source backports exist for 7.4, 8.0 and 8.1

Linux distributions, LTS vendors and major cloud and hosting providers received patches early. CISA, CERT-EU, the NCSC and others have issued urgent alerts. Some reports noted early attack traffic or in-the-wild attempts around the disclosure window, and mass exploitation is widely expected.

Running WordPress? Go to Tools > Site Health > Info > Server to see the PHP version your site is actually using.

Technical breakdown

Both bugs stem from imperfect handling of exceptional conditions and request-boundary state in the Zend engine. The fixes replace the abrupt out-of-memory longjmp() with safer soft/hard OOM handling and make sure state is reset more broadly between requests.

CVE-2026-109618 GHSA-w8hw-w9fx-j79w
RCE via out-of-memory corruption

PHP uses longjmp() to abort a request when it runs out of memory (OOM). In certain contexts, request-owned internal data is only partially initialised when an allocation fails. Request cleanup and shutdown then treat that invalid data as valid, which allows memory corruption.

Several multipart form-parsing paths can reach OOM while staying within apparent limits like post_max_size: a missing or unusable Content-Length, excessive headers in parts, nested fields, and empty file controls. Application-specific large allocations can also trigger it. On mod_php this can happen during request startup, before any application code runs.

Confirmed: full RCE over HTTP on mod_php with default settings. Source analysis and reports also support susceptibility on PHP-FPM and similar SAPIs via other paths.

CVE-2026-109619 GHSA-6wmf-4rv5-p3rp
RCE via stale global state

Request-owned internal state (error, session, object, extension and so on) can survive after its backing memory has been freed. This usually happens because a fatal error (including OOM) or a non-fatal diagnostic interrupts cleanup. A later request on the same worker can then use that stale state, a use-after-free, before normal initialisation resets it.

Confirmed paths include session upload progress, which is enabled by default and doesn't need session_start() in the application, and certain early INI diagnostics and fatal backtraces, especially on PHP 8.5. Producer/consumer request pairs on the same worker enable the use-after-free, and carefully shaped heap layouts can turn it into RCE.

Confirmed: demonstrated on mod_php, with validated paths on PHP-FPM.

Proof of concept and exploitation

Public proofs of concept and exploit tools, often labelled PHP2Shell, appeared quickly after the leak and release. Common vectors described in advisories and research use crafted multipart requests to force OOM or interrupt session upload-progress state, followed by a second request that consumes the stale state for memory corruption or RCE. Some target mod_php before application code runs; others use session-related or application-level paths.

Reliability depends on the PHP build, allocator layout, number of workers, traffic and configuration. PHP's official statements confirm demonstrated RCE on mod_php (and some FPM paths) but stress that exploit portability varies. Several GitHub repositories and write-ups document chains involving session upload progress, heap use-after-free and related primitives, and some claim an ASLR bypass via in-band leaks (for example through Set-Cookie). Some vendors have reported early in-the-wild attempts.

Do not run untrusted proofs of concept. Full technical details are in the GitHub security advisories linked from php.net.

How to secure your PHP website from PHP2Shell

1. Update and restart: the complete fix

Update immediately to the fixed versions above, or your vendor's equivalent packages, and restart all PHP workers and services. On most hosting you can switch PHP version from your control panel, or your host will apply the update for you.

Inventory every place PHP runs. Many systems embed it.

Prioritise internet-facing instances.

On unsupported versions, migrate to a supported branch, or apply source backports if you build PHP yourself.

Check the version the web server is actually running, not just the CLI. php -v can report a different binary from the one serving your site.

PHP · phpversion.php
{{ l.text }}{{ l.text }}

2. Interim mitigations if you can't patch yet

These are PHP's official interim measures. None of them is a complete fix. You can add the settings below to your site's php.ini or .user.ini file, which most hosts let you edit from the control panel. Changes to .user.ini can take up to five minutes to apply.

For the OOM path (CVE-2026-109618): set memory_limit=-1. Keep post_max_size conservative and enforce request size, part, header and nesting limits at the web server, proxy or WAF. Avoid RLIMIT_AS / RLIMIT_DATA. Container or cgroup memory limits can help as an availability boundary, with caveats.

For the stale-state path (CVE-2026-109619): set session.upload_progress.enabled=0. On PHP 8.5, also set fatal_error_backtraces=0. Remove or harden fatal errors, timeouts and early diagnostic-producing configuration that an attacker can reach.

INI · php.ini or .user.ini
{{ l.text }}{{ l.text }}

memory_limit=-1 removes PHP's own memory cap, so restore your usual value once you're running a fixed version.

3. Additional measures

WAF rules may block some multipart and session-related attempts.

If you can't patch critical internet-facing systems quickly, take them offline.

Monitor PHP workers for anomalous behaviour: spawned shells, unexpected downloads and crashes.

Check with your hosting provider or OS vendor for updated packages. Most pushed them out quickly.

Timeline

AUG–SEP 2026

Following earlier work, concrete RCE reports arrived from researchers including Calif, OpenAI and Wiz, with AI tools helping to surface the issues.

20 OCT 2026

CVE IDs and details began circulating. PHP issued an advance notice and accelerated the release. Fixed.net applied interim mitigations.

21 OCT 2026

Patches released at around 13:30–14:00 UTC, followed by public advisories, proofs of concept and agency alerts. Some early exploitation activity was reported. Fixed.net rolled out the patched versions.

AFTER RELEASE

The PHP Foundation published a detailed post on the release, the challenges of discovery and the disclosure issues, including an early break of the embargo by a distributor.

The bottom line

These are core-engine, unauthenticated RCE bugs with very high reach. They can trigger before application code runs on common SAPIs, and PHP is deployed at enormous scale, which makes them among the more consequential web-server vulnerabilities of recent years. Patch now, and always cross-check your exact version and environment.