On October 21, PHP released emergency fixes for two critical vulnerabilities. Before operators could deploy them, information was already circulating, patched images had appeared early, and defenders were reporting attacks. By the next morning, Cloudflare's CEO was talking about millions of attempts.
The useful questions are precise: when did researchers establish the risk, what escaped the embargo, what did defenders actually observe, and which packages fix the bugs?
Published October 22, 2026. All timeline times are UTC; add two hours for the Netherlands and Belgium on these dates. This article distinguishes observed attempts from demonstrated successful compromise.
What PHP2Shell actually affects
PHP2Shell covers
CVE-2026-109618, involving out-of-memory corruption, and
CVE-2026-109619, involving stale state between requests. Both can lead to unauthenticated remote code execution. Apache's
mod_php is especially exposed: a demonstrated path runs before application code. Other handlers need attention too, although their reachable paths differ. See the
OOM advisory and
stale-state advisory.
A CMS or framework update cannot replace the PHP runtime fix. Treat the runtime as its own asset, including copies in containers, hosting panels and appliances.
The timeline: discovery, disclosure and release
Chronology compiled from the PHP Foundation, Calif, AWS and Cloudflare. AWS's October 17 observation is retrospective, not a public warning issued that day.
Calif's account records a working RCE proof of concept shared on August 14 and confirmed by PHP on August 15. The discovery process had moved beyond a theoretical concern.
Read the researchers’ account. The engineering problem was then to deliver a fix across supported branches without breaking applications and extensions.
The Foundation's account identifies multiple disclosure failures. The initial CVE leak and Calif's accidental video both preceded Chainguard's publication. Blaming one person for the entire leak would flatten that sequence into a story the evidence does not support.
Chainguard's early release: what Lorenc confirms
Dan Lorenc acknowledges authorizing early publication. He cites exploitation reports and says the patched artifacts were public, including for non-customers. In the same LinkedIn discussion, the Foundation's Nils Adermann challenges the claim of confirmed exploitation, distinguishing probing from successful attacks.
Read Lorenc’s statement and Adermann’s response.
That disagreement matters. Releasing a patch can help defenders who can deploy it immediately, while giving attackers a concrete change to analyze before other distributors are ready. Our view: an emergency should trigger an explicit decision with the coordination group. A unilateral release carries consequences for everyone still waiting for a usable package.
AWS saw attempts before disclosure
Amazon Threat Intelligence reports a MadPot honeypot exploit attempt on
October 17, plus further attempts between
02:00 and 08:00 UTC on October 21. It could not establish whether those early attempts would succeed against real systems. Its report later describes broad exploitation after release.
AWS’s original report leaves the source of the attackers' advance knowledge unresolved.
For responders, the disclosure date is therefore a poor starting boundary. Preserve evidence covering the days before publication. Build the investigation around your actual exposure: reachable PHP handlers, runtime versions, worker lifetimes and the time the patched code went into service.
Cloudflare: thousands became millions
Matthew Prince
reported thousands of attempts in the ten hours before the announcement, tens of thousands within 45 minutes afterward, hundreds of thousands within two hours, and millions by his post at
01:25 UTC on October 22. These are Cloudflare's reported attempt counts, not compromised-server counts.
Cloudflare also
describes observing attack traffic and changing payloads. Its WAF protections add a defensive layer; the company still tells operators to patch PHP. A WAF alert is useful evidence for investigation. It does not, by itself, prove that the origin executed code.
Does PHP 8.5.12 actually fix it?
PHP lists 8.5.12 as fixed for both PHP2Shell CVEs. The same applies to the supported branch releases below.
The official advisory remains the reference for remediation.
| Branch | First fixed upstream release |
|---|
| PHP 8.2 | 8.2.35 |
| PHP 8.3 | 8.3.36 |
| PHP 8.4 | 8.4.27 |
| PHP 8.5 | 8.5.12 |
The “still works on 8.5.12” claim needs its correction attached. Researcher Elise
clarified the original post: it referred to a separate finding, not the vulnerabilities patched that day. That statement does not establish a PHP2Shell patch bypass. Nor does it establish that the separate issue has the same remote attack conditions. We found no confirmed bypass of these two fixes in the primary sources reviewed.
Older PHP: verify the backport, not just the version string
PHP supplied exceptional minimal source backports for 7.4, 8.0 and 8.1. Those are not a return to normal support, and they do not cover every obsolete version. Older deployments need an explicitly fixed vendor package or a supported upgrade path. Configuration changes alone are incomplete.
Check PHP’s guidance.
Distribution packages can retain an older upstream number. For example, Ubuntu lists
8.3.6-0ubuntu0.24.04.13 for its Ubuntu 24.04 PHP 8.3 fix. Verify the full package revision against the vendor notice rather than rejecting it because
php -v still starts with 8.3.6.
Ubuntu USN-8948-1
Patch the runtime. Investigate the exposure.

Inventory every runtime. Deploy the fixed packages, restart affected workers or replace containers, and verify the version actually serving requests. A successful CLI check cannot tell you which runtime a different FPM pool or container is using.
Then correlate web requests with PHP errors, process execution, file changes and persistence. A shell launched by a web worker deserves attention; an isolated HTTP 500 or a filename match needs context. Avoid running random “PHP2Shell checkers” on production systems during an already noisy response.
A patch closes the vulnerable path. If an attacker got in earlier, their access may survive it. Your incident response has to answer that second question.