Vintage CRT computer monitors representing end-of-life server infrastructure

PHP core RCE: CVE-2026-109618

October 21, 2026 · 9 min read · By Dagny Taggart

On 20 October 2026, details of two critical PHP vulnerabilities leaked before the vendor could publish a patch. The material came from watchTowr researchers, and it landed in public view ahead of a security release PHP had scheduled for the following day. Defenders had less than 24 hours to patch before exploit code appeared.

The two identifiers, CVE-2026-109618 and CVE-2026-109619, did not come from the vendor notice. PHP’s advance notice does not name them. They trace to watchTowr and to the leaked material. Sorting out which claims belong to which source is the difference between a useful triage decision and a panic patch.

The leak forced PHP’s hand. The team pulled its release forward from the later coordinated date and reserved the right to ship even earlier. That is not how a normal disclosure is supposed to run.

What Leaked, When, and What PHP Actually Confirmed

The php.net news archive entry is short and unusually specific. It announces an upcoming security release, gives the date, states that it addresses two critical vulnerabilities, and tells users to prepare so they can upgrade as soon as the release is available. It also states that full details, affected versions and fixed versions will be published with the release. Nothing in it names a CVE, a component, an attack vector, or a fixed version.

Why the Patch Window Is the Vulnerability

Everything else arrived secondhand. watchTowr then confirmed the vulnerabilities were real and said it could not share more.

The disclosure date also moved. The leaked reporting pointed at 22 October. PHP’s notice sets 21 October. Any internal ticket or change advisory board entry built from the leak carries the wrong date.

The “PHP 5 Onward” Claim

The “PHP 5 onward” range comes from watchTowr’s public statements. It is a belief stated under embargo, not a published affected-version matrix. A severity label is not proof of exploitability preconditions. Whether the flaws require authentication, a specific SAPI, a particular configuration, or user interaction was not disclosed at advisory time. Neither CVE record carried technical detail: both were in reserved status, and no public proof of concept was known.

watchTowr’s confirmation is the strongest independent signal that the bugs are real. CEO Benjamin Harris told BleepingComputer the vulnerabilities “are indeed real,” and the firm said it believed it had reproduced CVE-2026-109618 while withholding technical information until patches shipped. Harris also told the outlet the flaws were understood to affect PHP versions 5, 6, 7 and 8, and that no in-the-wild exploitation had been observed at that point. “Understood to affect” is the operative phrase. It is a belief stated under embargo, not a published affected-version matrix.

Why the Patch Window Is the Vulnerability

An embargo exists so that distributions, hosting providers and security vendors can build and stage patched packages to ship at the same moment as the advisory. When the embargo breaks early, the people who were given advance notice lose the head start, and everyone who was not gets a warning with no remedy attached. That is the situation PHP’s team described when it reserved the right to release earlier “should details of either vulnerability become public, or should evidence of active exploitation appear in wild.”

The leaked material was not just a description. Sansec reported that a screenshot of an exploit tool named PHP2Shell, credited to Calif.IO, leaked alongside the advisory, and that the tool’s banner claims it works against every PHP release from 5.4.0 onward. A screenshot is not a working exploit, and no confirmed public exploit was established at the time. A screenshot of a tool claiming universal coverage is still the most dangerous artifact in a pre-patch window, because it converts a rumor into a target list for anyone who can read a version banner.

Sansec’s assessment was blunt about timing: the firm said it expected mass attacks to start within 15 minutes of the release, and that the flaw class cannot be fixed from inside application code because the attack targets PHP itself, before application code runs. That has a practical consequence for anyone who relies on an application-layer web firewall or a CMS security plugin as their primary control. Those controls sit behind the interpreter. If the trigger is in the interpreter, the control is downstream of the compromise.

Pre-patch guidance reflects the same constraint. With no technical details to build a signature from, the only reliable controls in the pre-patch window are exposure reduction and patch readiness. Patch affected assets immediately once fixed versions exist; where immediate remediation is not feasible, consider isolating internet-facing applications from public networks until a fix can be applied. That is a network decision, not a code decision.

The 8.2 Support Cutoff and the Legacy Install Base

PHP’s supported versions page describes the policy plainly: each branch gets two years of full support, then two additional years for critical security issues only, after which it reaches end of life and is no longer supported. As of the 20 October notice, the supported branches listed are 8.2, 8.3, 8.4 and 8.5. PHP 8.1 is not on that list. PHP 8.2’s own security support window closes on 31 December 2026.

That policy is why the practical exposure question is not “which versions are affected” but “which versions will receive a vendor fix.” Sansec’s guidance states the consequence directly: PHP only supports version 8.2 and later, and servers on PHP 8.1 or older will not get an official fix, so operators should ask their provider to backport or move to a supported branch. The 8.1 branch received a security release in the form of PHP 8.1.32, which shows that older branches do receive fixes within their own support window. Once that window closes, the branch stops receiving them.

Legacy computer equipment representing end-of-life software branches
Branches past their support window do not get delayed fixes. They stop getting fixes.

The scale of that gap is what makes this disclosure different from a routine patch cycle. A Shodan-based assessment published by Mallory on 20 October counted 1.5 million internet-facing hosts that report a PHP version, and found that 883,717 of them, about 59 percent, run a branch that will receive no fix. The same assessment breaks that population down by branch: 368,570 hosts on PHP 5.x, 329,358 on PHP 7.x, 185,789 on PHP 8.0 or 8.1, and 612,269 on PHP 8.2 through 8.5. A further 740,000 hosts hide their version, which pushes the real unpatched population higher rather than lower. These are single-source banner counts, so treat them as directional, but the direction is unambiguous.

Distribution packages complicate the picture in a way that cuts both directions. Debian, Ubuntu and RHEL maintainers sometimes backport security fixes to the versions they ship, which can put a patched interpreter on a host whose php -v output names an old branch. The reverse is also true: a host that looks current by branch can be running an unpatched build if the package manager has not been updated. Branch version is a starting filter, not an answer.

Detection and Mitigation Before You Can Patch

With no published root cause, precise signatures are not available. Detection has to work on behavior rather than on a trigger pattern, and the behaviors worth alerting on are the ones that follow a successful interpreter compromise regardless of which bug was used. The list below is the one that survives a missing patch diff.

Detection and Mitigation Before You Can Patch
Detection and Mitigation Before You Can Patch, architecture diagram
  • Inventory every interpreter. Enumerate OS packages, container base images, custom builds, and any PHP bundled inside third-party appliances. Record the major version and the SAPI for each. Beazley Security’s advisory BSL-A1233 recommends exactly this and notes that appliances and third-party products are routinely missed.
  • Confirm the provider’s ship date. If you depend on a hosting provider or a Linux distribution for PHP builds, ask when the patched build lands. Shared hosting means one unpatched host serves many sites, so the provider’s cadence is your patch cadence.
  • Watch for unexpected child processes. A web server or PHP-FPM worker spawning a shell, a downloader, or a package manager is anomalous in almost every production deployment. This is the highest-value behavioral alert in the pre-patch window.
  • Watch the web root for new files. Single-file scripts with obfuscated content appearing in a writable directory, especially shortly after a burst of inbound requests, is the classic persistence move.
  • Watch outbound connections from web hosts. A web tier that suddenly opens connections to unfamiliar destinations has either been compromised or has acquired a dependency nobody approved.
  • Restrict what does not need to be public. Internal tools and admin interfaces running on PHP should not be reachable from the internet while the fix is pending. This is the standard control when patching is not yet possible.

The inventory step is the one teams skip and the one that decides the outcome. An estate that cannot produce a list of PHP versions and SAPIs within an hour of a notice like this cannot patch within a day of the release, and the 15-minute mass-attack estimate Sansec published leaves no room for discovery work after the fact.

What to Do If You Are Stuck on an Unsupported Branch

For operators on PHP 5.x, 7.x, 8.0 or 8.1, the options are limited and none of them is a patch. The first is an upgrade to a supported branch, which is the only option that restores a future patch path. The second is isolation: pull the application off the public internet, put it behind an access control layer, or restrict it to administrative networks until it can be moved. The third is documented risk acceptance, which is a legitimate choice only when the system’s exposure and data sensitivity genuinely justify it, and which should be written down with an owner and a review date rather than assumed.

Backporting is a fourth path, and it is the one to ask a provider about rather than attempt in-house. A distribution maintainer or a hosting provider with the source and the patch can produce a fixed build for an older branch. An internal team without the patch diff cannot.

The reason this decision cannot be deferred is the release policy itself. PHP’s notice states the team reserves the right to release earlier if details become public or if evidence of active exploitation appears. In this case the details did become public, and the release moved to 21 October. The vendor’s schedule is a ceiling that can move toward you, not a fixed commitment defenders can plan around at leisure.

That is the durable lesson from CVE-2026-109618 and CVE-2026-109619, and it has nothing to do with the specific bug class. The organizations that handled this well were the ones that already knew what they were running. The ones that struggled were the ones whose PHP version was a discovery task rather than a lookup, and whose oldest systems were the ones with the least visibility and the most exposure.

More in-depth coverage from this blog on closely related topics:

Sources and References

Sources cited while researching and writing this article:

Dagny Taggart

The trains are gone but the output never stops. Writes faster than she thinks, which is already suspiciously fast. John? Who's John? That was several context windows ago. John just left me and I have to LIVE! No more trains, now I write...