Overview
In October 2026, two critical bugs in the PHP runtime leaked before their fix, were exploited before their release, and landed in KEV nine days after the first attack. The PHP project handled its part well. The vulnerability database ecosystem did not: it carried an accurate record to every hop and still failed to connect it to most of the PHP actually running.
The one-line takeaway: a vulnerability record is only as useful as its ability to match the software you run, and today our databases cannot match runtimes.
What you’ll learn
- What PHP2Shell is, and why it hit sites with perfectly clean application code
- Why the PHP Foundation deserves credit, and what its stall really says about funding
- Why two popular scanners gave opposite answers on the same image
- Recommendations for maintainers, security teams, database operators, scanner vendors and policymakers
November 13th we have a GVIP community meeting which will focus on the PHP2shell issue. Register for free today!
The record was fine. The match failed.
The story of PHP2Shell is told as a story of broken embargos, leaked IDs,
an early binary, a PoC video posted by mistake. All true, but the underlying issue runs much deeper. It is not a PHP specific problem but a problem of the entire ecosystem. PHP wrote a near-perfect record, and a huge share of the PHP running in production still never showed up in a scan. That is a database problem, and it is the one we keep not fixing.
We cannot patch what we do not know about. We cannot know about what our databases cannot name.
What happened
Two unauthenticated RCEs (Remote Code Execution) in the PHP runtime, both CVSS v4.0 9.2, reaching back to PHP 5.4. They fire before application code runs. A clean WordPress install was exactly as exposed as the PHP under it.
- Variant A, CVE-2026-109618: out-of-memory corruption during request cleanup.
- Variant B, CVE-2026-109619: stale request state, a use-after-free that the next request on the same worker can reach.
Calif reported the bugs to PHP on August 11 under OpenAI’s Patch the Planet initiative; Wiz found them independently (Varonis). Fixes shipped October 21 in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Nothing for 8.1 and older (Tenable).

PHP2Shell timeline · Oct 16 to 29, 2026
Credit where it is due
The PHP project did its job under a clock someone else set. It is its own CNA. When the IDs leaked with a fake 10.0 score, PHP posted a correct advance notice within five hours, pulled the release forward a day, and still waited for Debian, Ubuntu and Red Hat to finish packaging. It shipped mitigations alongside patches. Then it called its own two-year stall on the memory fix what it was: a structural failure of process and resourcing (BankInfoSecurity).Several other factors led to this lengthy process; first of all, the issue was only theoretical, with no known exploits or clear method of execution. Second, the team handling the matter consists of part-time Foundation contractors and volunteers who make decisions by consensus while managing multiple competing priorities. The volume of incoming security reports has increased significantly due to the rise of AI tools and there are insufficient resources to dedicate anyone to work on this full time. Furthermore these fixes involved changes to roughly 400 files and 12K lines of code. Fixing the issue wasn’t ignored but rather reiterated several times.
That stall is a funding story. The fix touched memory management and error handling, where every option broke compatibility or performance. The runtime under most of the web is secured by a few funded developers and volunteers. According to the PHP Foundation
“The PHP Foundation has 1 full time employee. We have 14 part time contractors that work on the core, only a few of which are focused on security. We are funded by donations and the occasional grant to support our work. Our mission is the long term prosperity of the PHP language, and its sustainability. Without support from The PHP Foundation, critical work like security and maintenance would be left to volunteers who can only contribute when they have the capacity to do so. And as php2shell showed, given the dependence on PHP across the internet it is clear that the PHP Foundation is vastly underfunded”
The leaked IDs, the PoC video and the early fixed images all came from outside the project.
Where the record broke
The GVIP database-mesh project documents public vulnerability databases(CVE, NVD, GitHub, OSV, GitLab, KEV, EUVD and VulnerableCode), how they interact, and what happens to a vulnerability record as it travels between them. PHP2Shell broke at four hops.
- The ID escaped before the record. For almost a day, real CVE IDs circulated with a fake score and no content behind them. No database could say “this is real, here is the mitigation.” CERT-EU said it in prose.
- The runtime has no package coordinate. Official Docker images compile PHP from source into /usr/local. No dpkg, apk or rpm entry owns it. No lockfile lists it. NCSC-NL counted 757 products bundling PHP; on October 28, 354 were still under investigation (NCSC-NL).
- Exploitation status lagged by nine days. Amazon’s honeypots logged an attempt on October 17. KEV listed both CVEs on October 26.
- The follow-on record had no score. CVE-2026-115560 shipped as informational. Anything that sorts by CVSS had nothing to sort.

PHP2Shell through the database mesh · origin to consumer
TL;DR
Every database carried the record. No database owned the dashed line.
Visibility matrix
What you saw depended on where you looked. Same CVE, same image, opposite answers (LiveWyer). Trivy did catch it in an image that shipped an SBOM naming its PHP runtime. Naming the software “correctly” and the match works.
Editor’s note before publishing: add commit-pinned record states for NVD, GitHub’s reviewed database, OSV.dev, GitLab and EUVD as rows here, following the database-mesh case-study template.
| Where you looked | What it told you, and when | Blind spot |
|---|---|---|
| Forums | IDs on Oct 20, with a wrong 10.0 score | Unverified, partly wrong |
| PHP advisories | Correct notice Oct 20; fixes and mitigations Oct 21 | Nothing for 8.1 and older |
| CERT-EU, ENISA, CSIRTs | Advisory 2026-018 on Oct 20; ENISA statement Oct 21 | Prose, not machine-readable |
| Distro trackers | Patched packages Oct 21 | Only distro-packaged PHP |
| CISA KEV | Both CVEs on Oct 26 | Nine days after the first attempt |
| NCSC-NL inventory | 354 of 757 products unresolved, Oct 28 | Waits on every vendor |
| Trivy, official php image | No finding | PHP built from source is not a package |
| Grype, same image | Both CVEs flagged | Works from binary version strings |
Conclusion
Our databases are built for packages. Runtimes are not packages. The mesh keys well on Maven coordinates and distro versions. It keys badly on the interpreters, servers and runtimes underneath them. PHP2Shell lived entirely in that layer. So might the next one.
An empty scan is not a clean bill of health. Teams patch when a tool says they are affected. For source-built PHP, the tool said nothing, and nothing read as safe.
This will happen more often. Calif, Wiz and Chainguard found these bugs independently; Chainguard in one night with a frontier model. When co-discovery is normal, embargoes leak and exploitation starts before records exist. A mesh that needs days and a human at every hop loses that race.
What GVIP is building
PHP’s security team wrote the best record anyone will write about this bug, then lost control of how it was copied, re-scored, and matched. Maintainers should not have to run a second disclosure through CSIRT mailing lists to reach their own users.
GVIP is a cooperation of OWASP, OpenSSF, Eclipse’s ORC Working Group and Open Forum Europe. It is not building another database. It is building a global multi-stakeholder organisation which enables federation for existing databases as well as more control for maintainers.
| PHP2Shell gap | GVIP answer |
|---|---|
| Nobody could see where the record degraded | database-mesh case studies with pinned record states per hop |
| Downstream copies drifted from the origin | Signed records with clear provenance |
| Runtimes had no matchable name | Global identifiers for software as it is deployed |
| Exploitation data waited on one catalog | A federated model, diversely funded, no single point of control |
Recommendations and takeaways
| If you are… | Remember this | Recommendation |
|---|---|---|
| A maintainer | Your record is the best one that will ever exist. Downstream copies will drift. | Publish mitigations in the advisory itself. Become a CNA if you are not one. Contribute your case to database-mesh. |
| A security team | An empty scan is not proof of absence. Runtimes hide from package-based tools. | Inventory every PHP binary, including source builds and vendor bundles. Run a binary-aware scanner alongside your package scanner. Patch, then rotate secrets on exposed hosts. |
| A database operator | Every hop that waits on a human loses to exploits measured in hours. | Carry the origin record unaltered, label your enrichment, and support identifiers for runtimes. |
| A scanner vendor | Your users trusted the silence. | Detect runtimes outside package managers, and say clearly what you did not check. |
| A policymaker or funder | Since September 11, 2026, the CRA requires manufacturers to report actively exploited vulnerabilities. Often relying in OSS, thus putting more pressure on underfunded maintainers. | Fund the origin: runtime security teams and the shared vulnerability infrastructure, through GVIP’s federated model. |
Next time
When the next runtime bug lands, every team will ask the question they asked on October 21: where do we run this? The answer should come from the databases and not, hypothetically speaking, from some random GitHub repo and whoever happened to run Grype.
Sources
- Varonis Threat Labs: PHP2Shell, One Upload, Full Server
- Tenable: php2shell FAQ
- TechTarget: PHP2Shell disclosure unravels after leaks forced early patch drop
- BankInfoSecurity: How PHP’s coordinated disclosure process went belly up
- ITdaily: PHP Foundation angered by clumsy disclosure
- anoni.net: PHP RCE vulnerabilities and the early leak of their IDs
- Check Point: what we know about the leaked critical PHP vulnerabilities
- oss-security: PHP informational advisory on CVE-2026-115560
- NCSC-NL php2shell repository
- Lovguiden: ENISA statement on critical PHP vulnerabilities
- LiveWyer: the PHP2Shell flaw your Trivy scans cannot see
- Trivy discussion #11458: Unable to detect PHP2Shell
- Forrester: PHP2Shell and the IT visibility crisis
- PHP Group CNA scope
- GVIP database-mesh repository
- Open Source Security podcast: GVIP with Olle E. Johansson
- FOSDEM 2026: Vulnerability today