"Patch every PHP server. Today."
That was the message a lot of engineering leaders got the week of October 20. PHP2Shell is a pair of unauthenticated remote code execution bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619, both rated CVSS 9.2. Attacks started before the patches shipped, and working exploits followed within days.
The fix is an upgrade to PHP 8.2.35, 8.3.36, 8.4.27 or 8.5.12, or any later release on those branches. Patching every PHP server means first answering three questions with confidence: where are you running PHP, who owns each of those services, and what depends on them? The dependencies decide what gets patched first and what breaks if you take a service offline. When those answers live in spreadsheets and Slack threads, you get conflicting lists, forgotten services, engineers pulled off roadmap work, and leaders chasing owners for status all day. Teams that already know what they own and who owns it spend that same morning running a routine fix.
In Cortex, the response runs as one loop across hundreds of services:
A scorecard finds every exposed PHP service and grades it Reporting, Safe or Patched.
Each failing rule links to a self-service workflow, so owners get the fix where they already work.
An initiative sets the deadline, and failing owners get tickets and Slack reminders until they pass.
Leadership tracks progress by team in one executive view.
The sections below cover the fixed versions, where PHP inventories go wrong, and how to set up each step.
PHP2Shell fixed versions
PHP shipped fixes for the 8.2 through 8.5 branches on October 21, 2026, and every later release on those branches includes them. Anything on 8.1 or older needs a branch upgrade or a vendor package, since the PHP project isn't releasing one.
If you can't upgrade right away, PHP's advisory lists interim configuration settings. Treat them as a stopgap, since PHP is explicit that none of them make an installation safe.
For exploit mechanics and detection signals, Datadog Security Labs and Tenable have detailed writeups.
Find every PHP runtime in your environment
Most PHP inventories go wrong in the same handful of places:
Running
php -von a host reports the CLI binary. The FPM pool or mod_php module serving traffic can be a different version with different config.Container images and vendor appliances ship their own interpreter, so patching the host leaves them untouched.
Ubuntu, CloudLinux, TuxCare and other vendors backport fixes under the old upstream version number. A version check alone flags those servers as vulnerable when they're patched.
Wikis, admin panels and other internal tools bundle PHP and rarely show up in a service catalog.
Marketing sites, campaign microsites and seasonal promos often run on a PHP CMS that engineering has never inventoried.
composer.jsontells you which PHP version an app requires, which says nothing about the interpreter running it in production.
Each inventory source catches some of these and misses others, so combine them where you can.
For internet-facing sites, OpenAI's open source php2shell-checker reads the X-Powered-By and Server headers and classifies the version it finds. Plenty of production sites hide those headers, and the tool's own docs say an UNKNOWN result does not mean patched.
Track PHP2Shell exposure with a scorecard
A Cortex scorecard turns "are we patched?" into an answer that updates itself for every service in the catalog. The tempalte replaces the default Bronze, Silver and Gold levels with three named for where a service stands, and every rule is written in plain language, so security and engineering work from the same list.
Safe means safe for now. PHP is explicit that its interim settings reduce risk without making an installation safe, so every workaround should carry an expiry date, and Patched is the finish line every service needs to cross. Keeping the two levels separate also tells owners which job they have. A service on a backported 8.1 package is out of immediate danger but still needs a branch upgrade, and that work can run on a longer clock.
In the demo, each CI build sends the PHP version it ships to Cortex, and the rules check that value. Keeping the logic in CI makes the rules simple and cheap to evaluate. If you'd rather source the version from production inventory, config management or the repo, the rules stay the same.
Give developers a self-service path from failing to passing
When a service fails Reporting, the rule links straight to a Cortex Workflow that generates the CI build file for that repo. Developers don't have to interpret a security finding, since the next step is right there in the scorecard. Once the developer merges the change, the scorecard picks up the PHP version from the next build, and nobody has to tell security it's done.
Workflows close the reporting gap, but the upgrade itself still needs an owner who tests the app on the new version, especially for a branch jump off 8.1, where deprecations and extension changes can break things the security fix never touched.
Set a remediation deadline with an initiative
CERT-EU recommends isolating internet-facing applications until a fix is applied and verified, and CISA advises taking PHP systems offline if they can't be patched.
Dependencies set the order within that first group. A PHP service behind a public gateway or proxy is internet-facing even when its catalog entry says internal. A compromised service can reach whatever it's allowed to call, so one with credentials for production data or an internal admin API outranks an isolated tool. And if you can't patch a service and follow CISA's advice to take it offline, its dependents are what break. Keeping dependencies in the catalog next to ownership lets an owner check them before scheduling the fix.
Scale the fix across the org with a Cortex Initiative: it attaches a deadline to the scorecard. Connected to your ticketing system and Slack, it gives every owner of a failing service a ticket and regular reminders until the service passes, and progress rolls up by team, so leaders don't have to chase anyone. As a process rule, give every approved workaround an owner and an end date on or before the initiative deadline, so it can't outlive the remediation window without someone deciding it should.
Pick a deadline your org can hit. A company with hundreds of PHP services and a long 8.1 tail might set one week to reach Safe and a longer initiative to reach Patched.
Show leadership exposure and ownership gaps in one view
The Bird's Eye Report rolls every team up in one place, showing what's exposed, what's safe for now, and what's patched. Services with no owning team sit at the top, since those are the ones that fall through the cracks in an emergency, along with the long-running services nobody has touched in years. Leaders track one number instead of status across Slack threads and spreadsheets, and the work is done when every team hits 100%. Bring this view into the emergency review, and the separate status meeting goes away.
In the demo, the riskiest service is a seasonal promo site that doesn't report a PHP version at all. A known service on an old version at least has an owner and a fix date, while a site nobody inventoried has neither and is usually internet-facing by design. You can't patch what you can't see.
Unowned services are where remediation stalls, because reminders and tickets have nowhere to go. Cortex maps owners from your identity provider and Git, so a service whose owning team was dissolved in a reorg shows up as a gap you can assign, instead of a name in a spreadsheet nobody answers to.
Ownership gaps are worth tracking before the next CVE exposes them. In Cortex's DRIVE framework, ownership coverage is a core part of Vigilance, the pillar that covers security posture and vulnerability exposure. That puts the unowned-services count in your regular OpEx review as well as the emergency one.
Reuse the process for the next CVE
PHP2Shell needed a second patch cycle within two days, when PHP disclosed CVE-2026-115560, a separate issue the first fixes didn't cover. With the scorecard in place, a case like that is a rule change: once the fix ships, update the rules behind Safe and Patched and launch a new initiative. CI reporting, ownership data and the self-service workflow carry over untouched.
The same setup covers the next runtime CVE, whether it lands in PHP, OpenSSL or a Java logging library, because the rule is the only part that changes.
The video above walks through the full setup. To build a CVE-response scorecard on your own catalog, book a demo.
PHP2Shell FAQ
Which PHP versions fix PHP2Shell?
PHP 8.2.35, 8.3.36, 8.4.27 and 8.5.12, released October 21, 2026, and any later release on those branches. PHP 8.1 and older have no official release. Versions 7.4 through 8.1 have minimal source backports, and 5.4 through 7.3 are end of life with no fix. If you run packaged PHP, check your distribution's advisory.
Is PHP2Shell being exploited?
Yes. Exploit attempts started before PHP released fixes, and researchers have since recorded working shells on honeypots running unpatched PHP.
Does disabling session.upload_progress fix PHP2Shell?
No. It covers only part of the issue, and PHP says no configuration setting makes an installation safe, so upgrading is the fix.
How do I find every PHP version running in my org?
Combine CI build reports, production inventory and config management, and include containers and vendor images. Check the runtime that serves web traffic, since php -v on a host reports the CLI. Any service with no reported version should count as exposed until it reports one.
How should we prioritize PHP2Shell patching?
Start with internet-facing services, including internal services reachable through a public gateway or proxy. Then rank by dependencies: a service that can reach production data or an auth system comes before an isolated tool. Services with no reported version or no owner belong near the top, since you can't judge their exposure.
Why does my patched server still show an old PHP version?
Ubuntu, CloudLinux, TuxCare and other vendors backport security fixes without changing the upstream version number. Confirm against your vendor's advisory before marking a service as passing or failing.
What should we do with services on PHP 8.1 or older?
Move them to PHP 8.2 or later, or to a vendor's backported package in the meantime. CISA recommends taking PHP systems offline if they can't be patched or run 8.1 or earlier. Track every exception with an owner and an expiry date.



