A security bug is bad. A security bug in the software underneath an enormous part of the web is a different kind of problem. That is why PHP2Shell caused so much alarm this week.
But the story needs separating from the screenshots. This was not proof that every PHP website had been hacked, and the vulnerabilities were not first discovered two days before their scheduled announcement. What happened that late was a disclosure leak.
Reporting checked October 22, 2026. This is an explainer, not an assessment of any particular website.
What PHP2Shell actually was
PHP2Shell names two related vulnerability classes in PHP itself: CVE-2026-109618 and CVE-2026-109619. Researchers demonstrated unauthenticated remote code execution and process-memory disclosure. WordPress, Drupal and Joomla were demonstration targets, not the underlying cause. Updating a plugin would not repair a flaw in the runtime beneath it. The research collaboration included Calif, OpenAI Codex Security and Wiz. The researchers’ overview explains the scope.
That distinction matters. An application can validate its own inputs correctly and still inherit a dangerous failure in its execution engine. In the demonstrated Apache mod_php case, exploitation could happen before application code ran. The PHP security advisory rates the OOM issue Critical, 9.2 under CVSS v4.0, not the 10.0 circulated in early rumors.
How running out of memory became dangerous
The first bug lived in PHP’s handling of out-of-memory errors. When an allocation failed, PHP could abruptly jump out of the operation it was performing. That could leave an internal object reachable but only partially initialized. Cleanup then encountered that unfinished state as though it were valid.
Think of a building evacuation that starts while someone is assembling the emergency exit. Leaving quickly is not enough if the exit procedure assumes construction already finished.
This was more than making a request crash. Carefully controlled memory corruption could redirect execution. PHP’s fix changes the failure model: handle a soft memory-limit event at a safe point, or terminate the process at a higher hard limit rather than continue through unsafe cleanup. The confirmed execution privileges were those of the web worker, not automatic root access. PHP’s OOM advisory documents the mechanism and limits.
The second bug: a request that would not quite disappear
Web servers reuse workers across requests. Some PHP state persisted in a worker while referring to memory owned by an individual request. If that reference survived after the request’s memory was freed, a later request could encounter a stale pointer.
This is a use-after-free: the address remains, but the object it used to describe is gone. Reusing that memory can turn an old reference into access to something different. The results ranged from crashes and memory disclosure to demonstrated code execution. Exploitation depended on both a way to leave stale state and a later operation that consumed it in the same worker. PHP’s stale-state advisory explains those conditions.
Deployment details matter. Apache mod_php and PHP-FPM do not handle failed startup identically. Calif also demonstrated application-dependent execution paths under PHP-FPM, so “we use nginx” was not a sufficient safety argument. Calif’s research describes that distinction.
The strange “two days before”
The bugs were known privately well before the public scramble. Calif dates its discoveries to August 1, its first report to August 11, and PHP’s confirmation of its working demonstration to August 15. Calif publishes its discovery timeline. Wiz independently dates its discovery to August 19 and its report to August 24. Wiz publishes its own timeline.
The PHP Foundation says signs of the OOM problem had surfaced during work following a 2024 audit. Without a demonstrated execution path, a difficult fix stalled amid compatibility trade-offs and limited resources.
Then the coordinated rollout fractured:
October 20, around 15:00 UTC: the CVE identifiers circulated publicly, two days before the planned October 22 release. The Foundation says the initial leak contained no technical details.
October 20, 19:30 UTC: PHP issued an advance announcement and moved the scheduled release to October 21 at 14:00 UTC.
Around 20:00 UTC: Calif mistakenly published a demonstration video. Although deleted, copies circulated.
October 21, 07:41 UTC: according to the Foundation, Chainguard released patched images before the coordinated embargo ended.
This was a leak and an accelerated release, not a last-minute first discovery. The Foundation’s account details the disrupted disclosure.
How bad was it, really?
Bad enough to demand urgent patching, but not an excuse to substitute scary numbers for evidence. PHP’s large footprint is not a count of compromised sites. Configuration, runtime version, extensions and reachable application behavior affect exposure.
There was also more than laboratory research. Amazon reported an exploitation attempt in its MadPot honeypots dated October 17, before public disclosure, followed by further attempts on October 21. AWS explicitly said it was unclear whether those early attempts would succeed against real-world systems. Its report also described broad exploitation after release. That is evidence of hostile activity, not a verified global victim count. AWS’s threat-intelligence report preserves those important caveats.
What website owners should do
The first fixed upstream releases are PHP 8.2.35, 8.3.36, 8.4.27 and 8.5.12. Earlier releases in those branches need updating; older unsupported branches need a supported upgrade or a verified vendor backport. Install the runtime fix, restart the relevant workers, and verify what the running service actually uses. A new package on disk is not necessarily a restarted process. The coordinated upgrade guidance lists the fixed versions.
Ask your hosting provider whether its PHP runtime is patched. Review suspicious requests, unexpected child processes and file changes through the exposure window. AWS recommends investigating from at least October 17. Patching closes the vulnerability; it does not establish that an earlier compromise never happened. AWS outlines defensive checks.
Do not treat a single configuration flag as a universal fix. Temporary mitigations cover particular paths and may affect uploads, memory use or availability. The durable answer is the patched runtime, not a reassuring screenshot.
The larger lesson is simple: finding a serious bug and protecting everyone who depends on the software are different jobs. PHP2Shell exposed both a memory-safety failure and how fragile the time between private discovery and public protection can be.