October 29, 2026
PHP2Shell
Two Flaws, 70% of the Web as the Target, and the 11 Minutes That Could Have Saved Millions.

By Asad Syed
10 min read
Two Flaws, 70% of the Web as the Target, and the 11 Minutes That Could Have Saved Millions.
An executive briefing on the PHP2Shell vulnerabilities (CVE-2026โ109618 & CVE-2026โ109619)
Introduction:
At 2:14 a.m. on a Saturday, a single HTTP request slipped into the web server of Meridian Freight Solutions, a mid-sized logistics company. It carried no password, tripped no login, and triggered no alert. The server answered with a routine HTTP 200, and the application logs recorded nothing unusual. By the time anyone noticed, the attacker had read the database credentials straight out of memory, pivoted to the customer billing system, and quietly exfiltrated 400,000 shipping and payment records. The forensic bill, regulatory fines, and lost contracts would eventually total an estimated $12 million.
Here is the part that should make every security leader uncomfortable: Meridian had been warned. Three weeks earlier, their senior cloud architect had flagged the newly disclosed PHP2Shell vulnerabilities and requested an emergency change window to patch. The request was deferred.
_"It's an internal portal, it's behind our firewall, and we have a WAF. It can wait until the next maintenance cycle." _-VP, Meridian Freight Solutions
The VP did not want to risk any downtime before the quarter close. The patch that would have closed the hole would have taken eleven minutes to apply. The decision not to apply it cost eight figures.
Meridian Freight is invented, but nothing else in that story is. On 21 October 2026, the PHP project shipped emergency fixes for two critical flaws: CVE-2026-109618 and CVE-2026-109619, collectively nicknamed PHP2Shell. Each was rated a severe CVSS 9.2. These were not bugs in a plugin or a framework; they lived in the PHP engine itself, the runtime behind roughly 70% of all websites. An unauthenticated attacker could run commands on a server with nothing more than a crafted web request, before a single line of application code ever executed. It did not matter how carefully an organization had written its software or how meticulously they maintained application was exposed to precisely the same degree as a neglected one.
What makes PHP2Shell a landmark case is not the flaw but the clock. The underlying weakness had sat dormant in PHP for over a decade; what changed in 2026 was that frontier AI compressed the work of turning a theoretical bug into a working exploit from months into roughly a week. Attackers were probing honeypots four days before the vulnerability was even public, and within 24 hours of the patch, Cloudflare was logging millions of exploitation attempts, while 99.3% of measurable PHP servers still sat unpatched. The era when defenders could treat "patch available" and "exploit available" as weeks apart is over. For the Meridian Freights of the world, the distance between the two is now measured in hours, and the cost of ignoring that new reality is measured in millions.
This article examines how the PHP2Shell vulnerabilities work, how AI is reshaping the economics of exploitation, and for the organizations that cannot patch on day one, what compensating controls can keep a deferred patch from becoming a headline.
Affected and Fixed PHP Versions
PHP2Shell: An Inside Look for Executives
The PHP2Shell vulnerabilities are two critical flaws in the PHP engine itself, not in any application, plugin, or framework. Both lead to unauthenticated Remote Code Execution (RCE), meaning an attacker needs no password and no valid account to run commands on the server. Both are rated CVSS 9.2 (Critical). Here is how they work.
- CVE-2026-109618: Out-of-memory (OOM) memory corruption. When PHP runs out of memory mid-request, it aborts using a longjmp(), a hard jump that skips all normal cleanup and leaves request data half-built and uninitialized. An attacker who deliberately triggers that OOM condition can steer what the leftover memory contains and turn it into arbitrary code execution, all within a single request.
- CVE-2026-109619: Use-after-free / stale global state. A fatal error (out-of-memory, a timeout, or a dropped connection) aborts via the same longjmp(), leaving the engine's global and session state pointing at memory that has already been freed, for example, cached zval pointers or session upload-progress data. On the next request handled by the same worker, the attacker reclaims that freed memory with data of their choosing and executes code of their choice on your server.
What Happens in the Backend: A 60-Second Overview
Think of a PHP worker as a clerk processing one web request at a time at a desk. For every request, the clerk sets up the desk, does the work, and clears it off for the next customer.
- A normal request: set up the desk โ process โ clean up โ reset for the next customer. Every trace of the previous customer is gone before the next one sits down. Safe, orderly, and private.
- The sabotage: The attacker sends a request engineered to make the clerk run out of workspace at a precise moment in the mid-set-up.
- The flaw: Instead of carefully backing out, PHP's error handling makes the clerk bolt from the desk and skips the cleanup entirely. The desk is left with half-finished work and papers that no longer belong to anyone.
- The exploit:
- 4.1) CVE-2026-109618: The clerk's own final tidy-up step treats that abandoned, attacker-shaped scrap as if it were valid instructions and executes it. One request, done.
- 4.2) CVE-2026-109619: The mess is left on a shared notepad the next customer inherits. The attacker is the next customer, fills that space with their own content, and the clerk acts on it. Two requests: one to poison, one to trigger.
The result in both cases: the attacker is running commands on/as the web server, before any of the company's own application code is ever executed.
Why Should Executives Care About Mechanics?
- Your application quality is irrelevant. The flaw fires during request parsing, before a single line of your code runs. A flawlessly built, fully patched application is exposed to the same degree as a neglected one. This is not a bug your developers can fix.
- It is silent. A successful attack can return a normal "200 OK" response and leave nothing in application logs. You will not see it in the places you normally look.
- It leaks secrets, not just access. The same flaw can expose passwords, session tokens, and API keys sitting in server memory are a direct path into databases, cloud consoles, and connected SaaS, even without full code execution.
- Every web-facing PHP endpoint is an entry point. Login pages, contact forms, health checks, none of them need to be "reached" through the application to be attacked.
- Exposure is active, not theoretical. If you have internet-facing assets with these vulnerabilities, your chance of being exploited by an adversary has increased exponentially. Attackers were probing these flaws within days of disclosure, and automated, AI-assisted tooling now scans the internet continuously for exactly this kind of unpatched, accessible targets.
- The proof is in the wild. Wiz demonstrated unauthenticated RCE against stock WordPress, Drupal, and Joomla, and every web-serving PHP configuration (SAPI) is in scope.
- The trigger is broader than memory exhaustion. Because the fault is the bailout itself, this state can also be reached through execution timeouts and aborted client connections. Exploitation is therefore a two-stage operation: one request poisons the worker, a second triggers use of the freed memory [CrowdStrike].
The Disclosure Timeline and the AI Angle
The out-of-memory bug class was first spotted in 2024 during a Quarkslab audit funded by the Sovereign Tech Agency. Competing fixes each broke something, the work stalled, and the PHP Foundation later called the delay "a structural failure." The flaws were then reported three times in 2026: by Calif on 11 August, Wiz on 24 August (first found 19 August), and OpenAI on 18 September, before coordinated disclosure (Capital & Compute timeline; itwire).
The CVE IDs leaked around 15:00 UTC on 20 October with a wrong CVSS score (10.0) and no technical details; PHP shipped the emergency release the next day, 21 October 2026, at 14:00 UTC. Amazon's threat intelligence reported an exploitation attempt on 17 October that is four days ahead of disclosure and WAF vendors saw attack traffic around release (Recorded Future; itwire).
The reason these are grouped as a single disclosure event is the AI dimension. Wiz reported using its Atlas agent together with Gemini 4 Argon and GPT-5.6 Sol to find the flaws and, more notably, to adapt working exploits across PHP versions and CMS targets. Per Wiz, months of manual exploit development were narrowed to a couple of weeks because of AI. The bugs had existed in released PHP for more than a decade; what changed was the practical exploitability, which Wiz calls "an AI inflection point." A third, lower-risk RCE (CVE-2026-115560) was later reserved but, per the PHP Foundation, requires an unusual configuration unlikely in practice and is not part of PHP2Shell proper (The Register).
Why PHP2Shell Resisted Weaponization Before AI
The underlying bug class was not new. The out-of-memory flaw behind CVE-2026-109618 was first spotted in a 2024 Quarkslab audit, and the memory-limit bug class traces back to Stefan Esser's 2004 research. Yet no exploit path was known, and the fix stalled (itwire; Capital & Compute). The gap was in "exploitation engineering", not discovery.
Datadog names the two hard constraints an attacker faces: sizing a request so allocation fails at exactly the right moment, and defeating ASLR to find valid memory addresses (Datadog Security Labs). On top of that, a working chain must be re-tuned for each PHP version, SAPI, and build, because heap layout and offsets shift. That per-target adaptation is tedious, lab-heavy work that historically kept bugs like this in the "theoretically exploitable" bucket.
This is exactly the labor AI absorbs. Wiz described the chain as at the edge of what human researchers could practically achieve and said frontier models made it viable; Calif's Thai Duong described agents iterating on exploit development while researchers slept, compressing months into a couple of weeks (Wiz; Wiz podcast). The central point for executives: AI did not find a new bug class, it made an old one cheap to weaponize, and that economics applies equally to attackers once details are public.
Compensating Controls
No compensating control removes PHP2Shell. Patching the vulnerability is the only complete fix. That said, a layered set of controls can sharply cut the probability and impact of exploitation while a patch exception stays open. These controls act at four points along the attack chain, and each one buys resistance or delay:
- Reach. Zero Trust access gating and segmentation decide who can send a request to PHP at all. This is the strongest compensating layer because the exploit fires before any application login, blocking anonymous reach removes the pre-authentication path entirely.
- Trigger. WAF and virtual-patching rules inspect the request before it reaches PHP; they block known exploit shapes but can be bypassed via origin access or payload evasion.
- Vulnerable condition. PHP runtime settings (memory_limit, post_max_size, session upload-progress, fatal-error backtraces) remove specific trigger paths, but only few of those.
- Blast radius and detection. Least privilege, egress control, EDR, and log hunting limit what a successful exploit achieves and how long it goes unseen.
If you open an exception, each one should be time-boxed, owned, and documented. Every compensating control here assumes an attacker will eventually get past the one in front of it, so layer them, and treat the exception as temporary by design.
Summary and Conclusion
PHP2Shell is a pair of pre-authentication remote code execution flaws in the PHP engine itself, fixed on 21 October 2026 in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Both carry a CVSS v4.0 score of 9.2 and are classed as CWE-824 (access of uninitialized pointer), with CWE-416 (use-after-free) describing the cross-request variant.
Updating PHP to the patched release is the only complete fix. Compensating controls like WAF, controlled access to these resources, and the other layers from above, reduce risk and buy time, but they do not close the hole. Because exploitation leaves almost no trace, the window to act is before an incident, not after. The practical executive decision is simple: treat patching every Internet-facing PHP system as an emergency, and where a system genuinely cannot be patched, isolate it behind identity-based access controls and layer compensating controls until it can be or until it is retired.
PHP2Shell will be remembered less for its two CVEs than for how fast the window between disclosure and danger collapsed. On 21 October 2026, the PHP project shipped emergency fixes for both flaws across four supported branches at once (8.5.12, 8.4.27, 8.3.36, and 8.2.35) [1], yet the first exploitation attempt had already been logged on 17 October, four days before anyone outside the embargo knew the bugs existed [2].
Within the first 24 hours, Cloudflare counted "millions" of exploit attempts [3], and by 24 October researchers confirmed the first in-the-wild remote code execution on honeypots [4]. The scale of exposure is staggering: Censys's dashboard identified roughly 36.7 million internet-facing services reporting potentially affected PHP versions [5], and the flaw lives in the runtime behind an estimated 70% of all websites [6].
The Most Sobering Number: The Remediation Gap
One measurement found that 24 hours after the emergency patch, 99.3% of measurable PHP instances were still unpatched [7]; days later, more than one million internet-facing PHP servers were still running vulnerable releases [8], with PHP 8.1 and older end-of-life branches receiving no official fix at all [1].
PHP2Shell patched two vulnerabilities in a single day. It exposed a third one in the industry at large, a patch cycle that still measures itself in weeks, while attackers, armed with AI, now measure theirs in hours.
Thanks for your time!
Reference Resources
- [1] CISA, Critical Vulnerabilities in PHP Require Immediate Patching: cisa.gov/news-events/alerts/2026/10/21/
- [2] Wiz Research, PHP2Shell: AI Uncovers Critical RCE Vulnerabilities: wiz.io/blog/php2shell-php-rce
- [3] PHP security team advisory (oss-security, Jakub Zelenka): openwall.com/lists/oss-security/2026/10/21/6
- [4] GitHub Security Advisories: GHSA-w8hw-w9fx-j79w (109618) and GHSA-6wmf-4rv5-p3rp (109619)
- [5] CrowdStrike, technical runtime breakdown: crowdstrike.com
- [6] Zend / HeroDevs / Miggo CVE entries (109619 stale-state detail): zend.com, herodevs.com, miggo.io
- [7] Rapid7 and Qualys emergency advisories: rapid7.com, blog.qualys.com
- [8] NCSC-NL operational information: github.com/NCSC-NL/php2shell
- [9] Datadog Security Labs, How the Vulnerabilities Work: securitylabs.datadoghq.com
- [10] Censys PHP2Shell exposure dashboard (36.7M internet-facing services, 22 Oct snapshot)
- [11] Ox Security, 24 Hours In: 99.3% of Measurable PHP Instances Still Unpatched: ox.security
- [12] SecurityWeek, PHP2Shell Exploitation Started Days Before Patches: securityweek.com
Threat-Actor Activity and the AI Dimension
- Palo Alto Networks Unit 42, CVE-2026โ109618 / 109619 threat brief: unit42.paloaltonetworks.com
- The Hacker News, PHP2Shell Exploitation Attempts Continue Amid Suspected N. Korea Scanning (25 Oct, incl. Unit 42 retraction): thehackernews.com
- ReliaQuest, PHP2Shell: Responding to Critical PHP Vulnerabilities (AI lab reproduction): reliaquest.com
- AWS Security Blog, Amazon Threat Intelligence on pre-disclosure exploitation in MadPot: aws.amazon.com
- CYFIRMA, suspected DPRK campaign staging PHP2Shell targeting: cyfirma.com
- Capital & Compute, Who Found PHP2Shell? Calif, Wiz and OpenAI Timeline: capitalandcompute.net
- The Register, PHP2Shell Exploit Bypasses Protections (VulnCheck ASLR bypass): theregister.com
- Socket, PHP Foundation Says Chainguard Broke Security Embargo: socket.dev