Skip to content
PHP2Shell: The Timeline Behind PHP's October 21, 2026 Disclosures

PHP2Shell: The Timeline Behind PHP's October 21, 2026 Disclosures

October 23, 2026

On October 21, 2026, PHP published emergency releases addressing CVE-2026-109618 and CVE-2026-109619, collectively discussed as PHP2Shell. Both carry a CVSS v4.0 score of 9.2, Critical. The fixes shipped in PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12. The vulnerabilities concern PHP itself, rather than a particular application’s plugin or dependency. PHP release advisory.

The public release was the end of a longer investigation. This account follows discovery, reporting, coordination, and disclosure, rather than installation steps. Sources were checked on October 23, 2026. All clock times below are UTC. Earlier private milestones come from participants’ retrospective accounts; they were not necessarily public on those dates.

Before the public warning

2024: an unresolved failure mode. The PHP Foundation says a developer investigating Quarkslab audit findings recognized the OOM problem. Exploitation was theorized, not demonstrated. Compatibility concerns, competing fixes, and limited engineering capacity delayed resolution. Foundation retrospective.

July 30 to August 15, 2026: research becomes a working exploit. Calif dates its Patch the Planet audit to July 30 and its first discoveries to August 1. Its published chronology says Ryan Austin reported the first bug on August 11, supplied an RCE proof of concept on August 14, and received confirmation from PHP on August 15. Those are separate discovery, reporting, and validation milestones. Calif’s research account.

August 19 to September 21: independent reports and additional paths. Wiz dates its first discovery to August 19, its Drupal and WordPress RCE demonstrations to August 20 and 21, and its report to PHP to August 24. Calif separately records a second bug report on August 21. Wiz lists September 21 as PHP’s acknowledgment of its reports; that does not establish when the broader investigation began. Wiz disclosure timeline, Calif timeline.

The Foundation also credits an independent OpenAI report of the same root cause and additional OpenAI attack vectors on September 18. Foundation retrospective.

October 12: CVE identifiers reserved. The two records show reservation at 21:03:58 and 21:04:00, respectively. Reservation is administrative metadata, not a discovery or public-disclosure date. CVE-2026-109618 record, CVE-2026-109619 record.

October 20: the disclosure schedule changes

According to the Foundation, CVE identifiers circulated around 15:00, without technical details. PHP advanced its website warning to 19:30 and moved release from October 22 at 14:00 to October 21 at 14:00, allowing distributors some packaging time. Foundation account.

A separate, directly timestamped record is Jakub Zelenka’s 19:33:47 mailing-list announcement. It scheduled the release for the following day at 14:00 and allowed an earlier release if details became public or exploitation was observed. The email time and the Foundation’s website time refer to different publications. Original announcement.

The Foundation says Calif mistakenly published a demonstration video around 20:00, after the warning; copies circulated after its removal. Foundation account.

October 21: release and public records

The Foundation reports that Chainguard published patched images at 07:41, ahead of the coordinated release, and characterizes this as an embargo breach. Foundation account.

Several different timestamps then describe the public rollout:

Time on October 21What the source records
13:40ENISA’s joint statement says PHP issued the updates.
13:48:34Publication timestamp for CVE-2026-109618 in the CVE record.
13:54:43Publication timestamp for CVE-2026-109619 in the CVE record.
14:00Scheduled release time from the previous day’s announcement.
14:00:28 onwardRelease-email timestamps begin with PHP 8.2.35 on PHP’s announcement list.

Sources: ENISA statement, 109618 metadata, 109619 metadata, scheduled release, release mailing-list archive. CVE times are shown to the second.

These records support an October 21 release, but they should not be collapsed into one exact “disclosure time.” Package availability, advisory publication, CVE publication, and announcement timestamps describe distinct events.

PHP’s two GitHub advisories are also dated October 21. WordPress published its own warning that day, explaining that no WordPress release was required or planned for these PHP-runtime issues. OOM advisory, stale-state advisory, WordPress announcement.

Why these findings mattered technically

For CVE-2026-109618, an out-of-memory exit could interrupt initialization and leave cleanup handling invalid internal state. PHP confirmed unauthenticated RCE under Apache mod_php, including a path before application code executes. The resulting access is the web worker’s privileges, not automatically root. The fix changes OOM handling so it does not abruptly jump out of unsafe intermediate states. PHP’s OOM advisory.

For CVE-2026-109619, state retained by a worker could still point into freed request memory. A later request reaching that worker could consume the stale state before normal initialization replaced it. The advisory describes producing and consuming operations across requests, with affected conditions depending on the state and runtime path involved. PHP’s stale-state advisory.

That distinction matters when reading demonstrations. Wiz showed attacks against selected WordPress, Drupal, and Joomla deployments, but identified the bugs in the underlying runtime. A successful demonstration against one deployment does not show that every PHP configuration has an identical exploit path. Wiz research.

Who contributed, and what remains uncertain

The PHP-assigned CVE records credit Calif’s Ryan, Wiz, and OpenAI for discovery or reporting, and Arnaud Le Blanc, Ilija Tovilo, Jakub Zelenka, and Nora Dossche for remediation. OpenAI’s account describes coordination and technical support while explicitly placing fixes and release under PHP’s maintainers. CVE credits, OpenAI’s coordination account.

Public accounts do not establish every private exchange or identify the original source of the leak. The embargo account above is explicitly the Foundation’s account, not an independently reconstructed audit.

The Foundation said it had not identified functional exploits among circulating PoCs at release. That is a time-bounded observation, not proof of no exploitation. Foundation retrospective.

The chronology’s central lesson is how many stages sit between recognizing a dangerous failure mode and getting a coordinated release out. Research demonstrations established impact; maintainers still had to produce and validate a fix, and distributors needed time to deliver it. The public record is clearer when those stages retain their own dates.

This post was created with assistance from AI.

Last updated on