PHP2Shell (CVE-2026-109618 & CVE-2026-109619): What It Is, Who’s at Risk, and How to Shut It Down
The short version
On 20 October 2026, details of two critical vulnerabilities in PHP leaked online ahead of their planned coordinated disclosure. Together they’ve been nicknamed PHP2Shell, and they let an attacker run their own code on a vulnerable web server with no login, no password, and no user interaction. The PHP security team rates both at CVSS v4.0 9.2 (Critical) and confirms they can allow unauthenticated remote code execution. PHP shipped emergency fixes the following day, on 21 October 2026.
If your website or application runs on PHP — and PHP powers roughly 69% of all websites whose server-side language is known — treat this as a drop-everything, patch-now event.
The one-line action item: update PHP to 8.5.12, 8.4.27, 8.3.36, or 8.2.35 (or your distro’s patched build) now, and check whether you were already hit. CISA is urging organizations to patch immediately, because the flaws affect all PHP installations serving web requests.
What is PHP2Shell, in plain English?
Think of PHP as the engine under the hood of most of the dynamic web. When you load a WordPress blog, a Magento store, or a custom portal, PHP is the thing quietly turning code into the page you see. Normally that engine only does what the site’s own code tells it to.
PHP2Shell is a flaw in the engine itself. It’s the equivalent of a defect that lets a stranger on the street slip instructions straight to your car’s engine, bypassing the steering wheel, the pedals, and the locks entirely. And because the problem lives in the engine rather than in any one car, it doesn’t matter how carefully your application was built on top — the weakness is underneath all of it.
That’s what makes this one serious: it isn’t a bug in some obscure plugin that a few sites use. It’s in the foundation that a huge chunk of the internet is built on.
Under the hood: two bugs, one very bad day
PHP2Shell is actually two separate flaws that the PHP team patched together.
CVE-2026-109618 — RCE via out-of-memory corruption. PHP builds a set of internal data structures to handle each incoming web request. This bug stems from how PHP handles out-of-memory (OOM) conditions: if memory runs out while that request data is only partially initialized, the cleanup that follows can treat the half-built data as if it were valid. Acting on that corrupted internal state is the crack an attacker pries open into code execution — and an attacker can deliberately drive a worker toward that out-of-memory moment to hit the window.
CVE-2026-109619 — RCE via stale global state (a use-after-free). PHP reuses worker processes across many requests, which is great for performance but dangerous if state leaks between them. Here, leftover state from one request ends up pointing at memory that’s already been freed, and a later request handled by the same worker can then use it. That’s a textbook use-after-free. PHP’s advisory also lists memory disclosure as a confirmed impact — meaning an attacker can potentially read secrets or tokens left behind by other users’ requests.
Two details matter for defenders. First, both can be exploited by an unauthenticated remote attacker. Second, PHP considers the risk highest for Apache with mod_php, where a demonstrated exploit can be triggered by an unauthenticated request before any of your application code even runs. You can’t "code your way out" of a bug that fires before your code loads.
A responsible proof of concept
As pentesters, our job is to prove impact — not to hand attackers a loaded gun. That’s doubly true for a flaw that’s already being exploited and whose deepest internals we’d rather not amplify. Everything shown below was run against a lab system we are authorized to test, no working exploit code is published here, and sensitive output is redacted. What you can safely do yourself is this: confirm whether a server is exposed, and understand what a real attack would actually achieve.
Step 1 — Is this server even vulnerable? The fastest, 100%-safe check is a version comparison:
# Check the PHP version your site actually runs
php -v
php -r 'echo PHP_VERSION, "\n";'
# You're PATCHED if you're at or above:
# 8.5.x -> 8.5.12
# 8.4.x -> 8.4.27
# 8.3.x -> 8.3.36
# 8.2.x -> 8.2.35
# 8.1 and older -> no official package; upgrade or take offline
One important caveat: the CLI version can differ from the version actually serving web traffic (PHP-FPM or mod_php). Check the one your web stack uses — e.g. the "PHP Version" and "Server API" lines in
phpinfo()
, or your FPM pool. And don’t rely on the
X-Powered-By
HTTP header to fingerprint remotely; it’s frequently disabled, so its absence proves nothing.
Step 2 — What does a real attack look like? At a high level, both bugs are memory-corruption flaws reachable by an unauthenticated attacker over ordinary HTTP(S) — for example through specially crafted request handling that abuses PHP’s upload and error-cleanup paths. The researchers who discovered the chain published a deep technical write-up for anyone who wants the internals (linked at the end). In a controlled lab, the flow from "unknown target" to "foothold" looks like this:

Figure 1 — A PHP2Shell attack simulated against an authorized lab target. The exploit’s internals are deliberately withheld; what’s shown is the high-level flow from fingerprinting to payload delivery.
What matters operationally is the outcome: a successful exploit yields code execution with the privileges of the web-server account. Moments after the trigger lands, the attacker has an interactive shell:

Figure 2 — The attacker’s view seconds later: an unauthenticated request has become an interactive shell running as the web-server user, with database credentials one command away. Secrets are redacted.
From here, an attacker’s playbook is familiar — drop a web shell, read secrets like
wp-config.php
or
.env
(database credentials, API keys, session secrets), and pivot deeper into the network toward internal hosts like the database server. In other words, one unauthenticated request can become full server compromise.
Step 3 — About the "PoC" you’ll see floating around: be very careful. The PHP security team inspected the exploit code that surfaced after the leak and did not identify any functional exploits at the time of disclosure, and unverified exploit code is sometimes laced with malware. Running a stranger’s "PoC" against your own servers is a great way to compromise them yourself. Verify exposure with a version check; prove exploitability with controlled, authorized testing — not copy-pasted paste-site code.
Your questions, answered
Does the attack require authentication?
No. Both vulnerabilities are unauthenticated — no account, token, or user interaction needed. On Apache mod_php, the demonstrated exploit can be triggered before any application code runs, which is the worst-case profile for a web vulnerability.
Who is affected?
Almost anyone running PHP to serve web traffic. Because the flaw is in PHP itself, every major PHP application sits on top of the vulnerable code — researchers confirmed pre-authentication remote code execution against specific versions of WordPress, Drupal, Joomla and Magento. Every serving configuration is affected: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. The earliest affected code path dates back to PHP 5.4.0, so in practice every PHP version from 5.4 through the unpatched 8.x builds. Researcher estimates put the number of internet-exposed, potentially vulnerable hosts at well over a million — one estimate exceeds 1.3 million, and a Shodan count found over 1.9 million exposed hosts running PHP.
Is it being exploited in the wild?
Yes, and early. Cloudflare reported seeing early attacks emerging within a day of disclosure, and watchTowr said it reproduced both vulnerabilities and is observing exploitation attempts against both. Given the leak and the size of the attack surface, expect mass scanning and exploitation to accelerate quickly.
How bad is the impact, really?
Both score 9.2 (Critical) on CVSS v4.0. A successful exploit means arbitrary code execution as the web-server user: data theft, web shells, ransomware staging, and lateral movement are all on the table — and CVE-2026-109619 can additionally leak memory, exposing secrets from other requests.
I’m behind Cloudflare or a WAF — am I safe?
Safer, not safe. Cloudflare has deployed WAF rules for the known exploit vectors to all customers, including the free tier, but describes this as a stopgap only, and the rules only cover traffic routed through Cloudflare. New attack vectors can slip past static rules. A WAF buys you time; it does not replace patching.
I’m stuck on an end-of-life PHP version — now what?
PHP 7.4 through 8.1 receive minimal source backports from the PHP security team for those who build from source, but no official packaged release; versions 5.4 through 7.3 get no fix from the project. The real answer is to upgrade to a supported, patched branch. If you truly can’t yet, pull the patched build from your Linux distribution or LTS vendor and, following the UK NCSC’s guidance, consider taking offline any system that can’t be fixed right away.
Could my server have been compromised before the patch existed?
Possibly — so check. Public reporting suggests the vulnerabilities may have been known to third parties as early as August 2026, so reviewing activity on exposed systems from 1 August 2026 onward is recommended.
How to remediate
1. Patch now — it’s the only complete fix.
| Your PHP branch | Fixed version |
|---|---|
| 8.5.x | 8.5.12 |
| 8.4.x | 8.4.27 |
| 8.3.x | 8.3.36 |
| 8.2.x | 8.2.35 |
| 7.4.x – 8.1.x | No official release — minimal source backports only |
| 5.4.x – 7.3.x | End-of-life — upgrade to a supported branch |
Linux distributions and LTS vendors received the patches in advance, so if you install PHP from your distro, grab the patched package from your vendor rather than building from source. After updating, restart your web stack so every worker picks up the new build.
2. If you genuinely can’t patch this minute, apply interim mitigations that reduce — not eliminate — exposure. For CVE-2026-109618, set
memory_limit = -1
in a way your applications can’t override, and consider a container or cgroup memory limit as an availability boundary. For CVE-2026-109619, set
session.upload_progress.enabled = 0
, and on PHP 8.5 also set
fatal_error_backtraces = 0
. Restart every PHP worker after making these changes. Put a WAF in front, and per CERT-EU’s guidance, isolate internet-facing applications from public networks until a fix is applied and verified. Be honest with yourself about what these are, though: tourniquets. PHP’s own team says updating is the only complete fix.
3. Assume breach, then hunt. Because exploitation may predate the patch, treat any exposed, unpatched server as potentially compromised until proven otherwise. Look for newly created or modified PHP files and web shells, unexpected outbound connections, and new admin users; rotate every secret that lived on the box (database credentials, API keys, session keys,
wp-config
/
.env
values); and review access logs from 1 August 2026 onward.
4. Harden for next time. Keep PHP on a supported branch — note that PHP 8.2 reaches end of life on 31 December 2026 — minimize your exposed surface, disable features you don’t use, and run least-privilege web-server accounts so that if an RCE ever does land, it buys the attacker as little as possible.
The hard part isn’t patching — it’s finding every PHP server you forgot you had
The organizations that get burned by PHP2Shell won’t be the ones who couldn’t patch. They’ll be the ones who didn’t know where all their PHP was. The forgotten staging box. The legacy marketing microsite. The server that came with an acquisition. The vendor-managed app nobody owns. With well over a million exposed PHP hosts on the public internet, the real question isn’t "is PHP risky?" — it’s "do I know every place I’m running it?"
That’s the gap external attack surface management closes. Mitral e-ASM continuously discovers your internet-facing assets and fingerprints the software behind them — PHP versions included — so you can see within minutes which public endpoints are exposed to PHP2Shell and prioritize them before attackers do. And when you need to go from "which versions are exposed" to "which of these is actually exploitable, and what’s the blast radius," Mitral PTaaS combines continuous and manual testing with findings tracking and retests, so you can confirm you’re genuinely covered once the patches are in.
Not sure where you stand right now? Run a free external scan on hiperlinx.com and get a first look at your exposed PHP footprint.
Sources & further reading
- PHP.net security advisory (21 Oct 2026): https://www.php.net/archive/2026.php#2026-10-21-5
- PHP GitHub advisory — CVE-2026-109618 (OOM corruption):
GHSA-w8hw-w9fx-j79w - PHP GitHub advisory — CVE-2026-109619 (stale global state):
GHSA-6wmf-4rv5-p3rp - CERT-EU Security Advisory 2026-018: https://cert.europa.eu/publications/security-advisories/2026-018/
- CISA alert (21 Oct 2026): https://www.cisa.gov/news-events/alerts/2026/10/21/critical-vulnerabilities-php-require-immediate-patching
- Calif technical write-up: https://calif.io/php2shell/
