Four Teams Found the Same PHP Bug. The Embargo Broke Anyway.
The patch landed at 14:00 UTC on 21 October: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, four branches carrying the same fix for two memory-corruption flaws. Both are scored 9.2, and on Apache with mod_php an unauthenticated request can reach the vulnerable path before any application code runs [1][3]. At 07:41 UTC that morning, Chainguard published built images containing that fix and made them available outside its customer base [1][6].
That is six hours and nineteen minutes ahead of the coordinated release, and the PHP Foundation’s postmortem gives it one sentence: “Any attacker could now study the fix in binary form while every other PHP user was still waiting for the release.” [1]
I understand why that is the line people quote. I don’t think it is where the weight belongs, because by the morning of 21 October the embargo had already failed in more than one place. Amazon’s MadPot honeypot network recorded proof-of-concept exploits in circulation from around 02:00 UTC that day, and exploitation attempts against its sensors between 02:00 and 08:00. Chainguard published built images at 07:41, so Amazon had been watching people try for nearly six hours before it [5]. The two CVE identifiers had been on forums and social media since roughly 15:00 the previous afternoon, bundled with the wrong release time and a CVSS score of 10.0 against an actual 9.2 [1].
I am less interested in who broke this embargo than in what the disclosure measured. Four teams held the same root cause before the release, an exploitation attempt turned up on honeypots four days before it, and the schedule still came apart two days ahead of the date the maintainers had set. That is what a timetable looks like when several parties can find the same bug and none of them needs the official advisory to act.
I have made three related arguments here before: that discovery compressed while remediation did not, that attacks now move faster than the defense built to answer them (the agentic gap), and that the embargo lost its secrecy premise once an agent could work from a rumour rather than the details. This event landed eighteen days after that last piece and is the test of it, so I have tried not to restate the theory.
The bug was twenty-two years old
Stefan Esser published the first PHP memory-limit remote vulnerability in 2004, and Calif’s write-up notes that two commercial exploit vendors built non-public exploits from it [4]. In 2020 someone filed PHP bug #78876, long variables causing an out-of-memory condition plus temporary files that were not cleaned up [4]. In 2024, during the first external security audit in years, a core developer contracted by the PHP Foundation found “the first signs of the OOM problem” while fixing an issue Quarkslab had reported; a potential exploit was theorized but no concrete vectors were found, so it stayed open [1]. The Foundation had arranged that audit through OSTIF with Sovereign Tech Agency funding. Calif’s account of the same audit is that it rediscovered the out-of-memory issue and left it unfixed because exploitation was unproven [4].
The Foundation does not soften what happened next: “We won’t pretend otherwise: the delay was a structural failure, caused by both the security team’s decision process and its lack of resources.” [1]
One root cause, four holders
Calif began auditing PHP on 30 July under OpenAI’s Patch the Planet programme, surfaced the first out-of-memory fatal chain on 1 August, and reported the first bug to the maintainers on 11 August, which opened the coordinated process [1][4]. A working remote code execution proof of concept reached PHP on 14 August and was confirmed the next day. A second bug followed on 21 August [4].
Wiz found the same class of flaw on 19 August using Wiz Atlas with Gemini 4 Argon and GPT-5.6 Sol, had unauthenticated code execution against Drupal the next day and against WordPress on the 21st, and reported to PHP on 24 August [3]. OpenAI reported the same root cause independently and sent further attack vectors on 18 September [1].
The fourth find came later. Dan Lorenc, Chainguard’s chief executive, heard on Friday 16 October that something was coming in PHP. That night, with his company’s AI harness and a frontier model, he and his team found the same memory corruption vulnerabilities [6]. His account of the effort is short: he wrote that all it took was a basic prompt telling the model to find bad vulnerabilities in PHP [6]. The sentence I would keep from the whole event is the one he gave The Register. “Just being told there’s a vulnerability in a piece of software - even something as big as PHP - is enough to find it” [6].
Ryan Austin at Calif pushes back on the framing, and he is worth listening to because he did the other three months of work. “No special harness, or access to models that weren’t generally available to everyone were used in the initial bug discovery.” [4] He also argues that no model is simply capable of unearthing all bugs with simple prompts, at least for now, and his account of why the work succeeded is that he picked a target whose vulnerability history he knew and prompted in the direction of Esser’s 2004 finding [4].
Both of those are true, and they describe one mechanism from opposite ends. The prompt does not need to be clever when the target is named. Once a rumour establishes that a specific piece of software has a memory-limit bug in request handling, a researcher with a model converges on it in a weekend, and Lorenc did exactly that from a rumour in one night. The change does not require a model to be superhuman at finding bugs. It requires the rumour to be cheap to act on, which it now is.
Seventy-one days, almost none of it discovery
From the first report on 11 August to the release on 21 October is 71 days. From the first find on 1 August it is 81 [1][4]. The audit produced its first finding within days of starting. Almost none of the elapsed time went into discovering anything.
Where it went is specific, and the Foundation wrote it down. To fix the out-of-memory problem the security team developed several competing approaches, each with its own cost: backward-compatibility breaks, new denial-of-service exposure, or changes to many third-party extensions that could not realistically be coordinated. The team “struggled to choose between these and feared the repercussions of shipping the wrong choice” [1]. With a small group of core developers who knew the engine well, and no known path to code execution for most of that period, the work stalled and restarted over months [1].
The most useful sentence in the post is about what tooling cannot do: “What tools cannot do is decide on the right fix for a long-standing design decision in the engine, weigh the compatibility trade-offs, and review the patch.” [1]
The volume problem is in the same post. Since 1 July the security team has published 15 CVEs and worked through more than 100 reports that were invalid, duplicates or not reproducible, and “a person makes every call and works on every patch” [1]. OpenAI said the same thing in June when it launched Patch the Planet, that “AI is accelerating vulnerability discovery, but discovery alone does not protect users”, and that maintainers were already being asked to sort through more reports, more quickly, with the same limited time and resources [8]. Trail of Bits engineers reviewed every finding before it reached a maintainer [8]. Brockman’s essay calls the alternative an “anti-goal to simply produce more security findings that need human validation” [7].
The decision, and the one place it can be dated
The sequence on 20 October is in the Foundation’s post, hour by hour. The two CVE identifiers started circulating at about 15:00 UTC carrying a 10.0 that was wrong, with no technical details attached [1]. PHP brought its pre-announcement forward to 19:30 UTC and moved the release from the 22nd to the 21st, holding at 14:00 UTC, because distributors were still packaging and releasing immediately would have left users without a clean upgrade path [1]. Around 20:00 UTC Calif mistakenly published a video showing its proof of concept against several targets. Copies circulated after it was deleted, and the Foundation says it accelerated other people’s exploit development [1]. Mitigation advice that had begun going to a few unspecified critical-infrastructure providers from about 23:00 UTC may have leaked as well [1].
Chainguard’s call came late that night. Lorenc says he notified the PHP coordinated disclosure channel of his intention before shipping [6]. On the Saturday, before any of this, Chainguard had begun working with the maintainers, confirmed that some of its own findings matched the bug reports, and helped test the patches [6].
The Foundation’s description is a unilateral break: “On October 21st at 07:41 UTC, more than six hours before the coordinated release, Chainguard unilaterally broke the embargo and published built images containing the fix.” [1] Lorenc does not dispute the timeline and disputes the conclusion. His company “didn’t leak.” He told The Register the decision was a policy call [6]. His justification is the trigger clause in one sentence: “It’s coordinated vulnerability disclosure, unless there’s evidence of active exploits in the wild.” [6] He said he would make the same call again, and described the policy as coordinating as far as possible until people start weaponizing things [6]. Chainguard’s honeypots caught IPs from China and Russia targeting the vulnerabilities that Wednesday, he added [6].
The checkable part is narrower than either account implies. AWS’s telemetry corroborates the trigger without establishing what Lorenc knew at 07:41: proof-of-concept exploits were circulating and hitting its sensors from 02:00 UTC, nearly six hours before Chainguard moved [5]. AWS is careful about its own evidence, saying it is unclear whether any of those attempts would have succeeded in real systems and that the addresses involved are shared anonymization infrastructure rather than infrastructure unique to this activity [5]. What the record can establish, without settling Chainguard’s case, is a timetable that outsiders were already reading. The CVE identifiers were on forums and social media from about 15:00 the previous afternoon, a proof-of-concept video was public for part of that evening, and the Foundation had brought its own release forward by a day in response [1].
The word “window” belongs to a vendor
“Defender’s Window” is not a phrase someone applied afterwards. It is the title of a signed essay Greg Brockman published on 17 August 2026, sixty-five days before the PHP disclosure, which closes: “The defender’s window is open now.” [7] The disclosure post two months later reuses it as a capitalised proper noun and links back to the essay: “To our knowledge, frontier AI found these vulnerabilities before attackers did, opening a Defender’s Window for maintainers and security providers to prepare fixes and protections ahead of disclosure.” [2]
Two things in that sentence are worth separating. The qualifier at the front is doing real work, because the public record contains an exploitation attempt on 17 October, four days before disclosure [5]. An attempt in somebody’s honeypot four days early does not settle who found the bug first, and I have not seen anything that does. Then there is the noun: what opened on 1 August was a fix window for one maintainer team. Whether it was a defender’s window depends on whether defenders could use it, and the ones who could were the ones already admitted.
Access to the capability is gated and subsidised by the company that named it. OpenAI has committed $1 billion in subsidised Daybreak access, aimed at organisations with limited security resources protecting essential services [2]. GPT-6 Cyber went out on 5 November “to a select group of approved Daybreak Red customers” [9]. The PHP Foundation got PHP into Patch the Planet, scanned it with Anthropic’s Claude Mythos through Alpha-Omega, and used Daybreak Red for validating reports and exploits [1]. Wiz used its own Atlas tooling, and credited Gemini 4 Argon with an invaluable contribution to finding the vulnerability [3].
None of that is a conspiracy. A vendor paying for maintainer work on widely used open source is a real benefit, and the Foundation says plainly that without its funding it could not have had several people working on the issue full time [1]. A capability you need to be admitted to, though, is a procurement problem before it is a security problem. The asymmetry in this event does not run between defenders and attackers. It runs between parties holding frontier cyber models and the language foundation that runs a large share of the web, which had tool access through a grant programme and 71 days of argument ahead of it.
OpenAI also wrote the argument against its own durable advantage, in the disclosure post, about when distributors and providers need time to prepare: “which may be in short supply if frontier capabilities are not too far ahead of those that are broadly available” [2]. Brockman’s essay already noted that competitors had released models “only a few months behind the frontier” [7]. A window that closes as diffusion catches up is a gap rather than an advantage, and this one is measured in months.
What I would take from it
The most operationally useful thing published on this event is AWS’s pair of lessons, and neither is about AI finding bugs. The first: “An embargo protects defenders only until someone else finds the same bug.” [5] The second is that “AI-assisted analysis makes it cheaper to turn a patch diff or advisory into a working exploit”, so measure patch and mitigation timelines for internet-facing systems in hours rather than days, and start investigations from the earliest known exploitation instead of the advisory date [5]. A seven-day or thirty-day SLA assumes a delay that no longer exists [5].
For maintainers, the lesson is not that they should go out and get an agent of their own. It is that the constraint moved downstream. If a rumour is enough for a competent researcher to produce a working exploit over a weekend, then secrecy buys only time, and time converts into protection only if somebody can make a decision inside it. PHP’s answer is a process change, decisions by majority with compromises encouraged, plus money for people who know the engine [1]. That is a slower, duller fix than a model subscription, and it addresses the part of the 71 days that models could not touch.
Coordinated disclosure has always been a schedule agreed among people who trusted each other not to look too hard. PHP2Shell is what that schedule looks like when looking is nearly free. Four parties held the same root cause before the release, the last of them getting there with a basic prompt on a Friday night, and the two identifiers were on forums and social media the afternoon before the fix went out [1]. The Foundation’s post calls the 07:41 publication a unilateral break of the embargo [1]. Chainguard’s chief executive says his company did not leak, and that the decision was a policy call taken because there was evidence of active exploits in the wild. He says he would make the same call again [6].
Sources
- Today’s PHP Security Release, and How We’re Strengthening PHP Security — The PHP Foundation, 21 Oct 2026
- Patch the Planet: global response coordination as agents uncover critical vulnerabilities — OpenAI, 21 Oct 2026
- PHP2Shell: AI uncovers critical RCE vulnerabilities affecting 70% of the Internet — Wiz Research, 21 Oct 2026
- PHP2Shell: A tale of two PHP remote vulnerabilities — Ryan Austin, Calif Research
- Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot — AWS Security Blog, 21 Oct 2026
- PHP blames supply chain security biz Chainguard for putting huge chunks of the web at risk — Jessica Lyons, The Register, 21 Oct 2026
- The Defender’s Window — Greg Brockman, OpenAI, 17 Aug 2026
- Patch the Planet: a Daybreak initiative to support open source maintainers — OpenAI, 22 Jun 2026
- GPT-6 Cyber: Advancing the frontier of aligned cybersecurity agents — OpenAI, 5 Nov 2026