PHP2Shell: The PHP Flaw Hiding in Your Firewall, Your Guest Wi-Fi, and Your Website
If your first reaction to "critical PHP vulnerability" was "we don't run PHP," hold that thought for about five minutes. PHP2Shell is not a WordPress plugin bug or a Drupal module problem. It is a pair of flaws in the PHP runtime itself, and that runtime sits underneath a surprising amount of the gear health care IT teams depend on: firewall management consoles, guest Wi-Fi captive portals, network monitoring tools, help desk systems, and the public website your marketing vendor built three years ago.
Here is what happened, where PHP is likely hiding in your environment, and what to do about it in priority order.
8.3.36 | 8.2.35
- Inventory PHP, starting with internet-facing systems and guest Wi-Fi captive portals.
- Update to a fixed release, then restart every PHP worker and verify.
- If you cannot update yet, set
session.upload_progress.enabled=0at the server level and restart. - If you can do neither, take the system off the internet.
- Review logs back to October 17, 2026, not October 21.
- Document what you found and what you did.
What Happened
On October 21, 2026, the PHP project released emergency updates for two vulnerabilities, CVE-2026-109618 and CVE-2026-109619. PHP rates both at 9.2 under CVSS v4.0 and states they can allow unauthenticated remote code execution. Researchers have been calling the pair PHP2Shell.
The release was supposed to happen on October 22. Details leaked online on October 20, and the PHP Foundation moved the patches up by a day. It turns out someone had a head start even before the leak. Amazon Threat Intelligence recorded an exploitation attempt against its MadPot honeypot network on October 17, four days before public disclosure, and says it is unclear how the actor obtained exploit details while the issue was still under embargo.
In plain terms, both bugs are memory-handling mistakes in how PHP sets up and tears down web requests. CVE-2026-109618 involves PHP running out of memory partway through setting up a request and then cleaning up data that was never properly initialized. CVE-2026-109619 involves leftover state from one request being reused by a later request handled by the same worker process. Either way, an attacker who can send crafted requests to a vulnerable server may be able to run code as the web server's PHP process. The detail that matters most for prioritization: on Apache with mod_php, PHP says the attack can trigger before any application code runs. Your application can be perfectly patched and written well, and it does not matter.
How Worried Should You Be?
Worried enough to act this week, not worried enough to unplug the hospital.
On the "act now" side, attack traffic is real and heavy. Cloudflare CEO Matthew Prince reported thousands of attempts in the 10 hours before the announcement, hundreds of thousands within two hours after, and millions by the following morning. Amazon describes PHP2Shell as seeing broad exploitation attempts in the wild. watchTowr, which reproduced the vulnerabilities, reported exploitation activity against its honeypots starting October 21, and Wiz demonstrated unauthenticated code execution against current WordPress, Drupal, and Joomla container images.
On the "don't panic" side, an attempt is not a compromise. In statements made between October 21 and October 22, Germany's BSI, the Dutch national cyber agency, Japan's government, and CISA all said publicly that they had not confirmed successful exploitation, and the BSI noted that exploitation appeared harder than expected. Reliable exploitation depends on the PHP version, the server configuration, and how PHP is wired into the web server. As of watchTowr's October 22 update, neither CVE was in CISA's Known Exploited Vulnerabilities catalog.
That gap between "millions of attempts" and "no confirmed break-ins" is exactly the window you want to close. Attackers adapt quickly, and the scanning is indiscriminate. It is very unlikely anyone is targeting your hospital specifically. They are spraying every PHP server on the internet and waiting to see what sticks.
Where PHP Is Probably Hiding in Your Environment
This is the part most teams will underestimate. PHP shows up in a lot of places that nobody thinks of as "a PHP server."
Picture a 25-bed Critical Access Hospital with a two-person IT team. They run Windows and Active Directory, an EHR hosted by their vendor, and nothing they would describe as a PHP shop. Now look closer. The public website is WordPress, built and hosted by a regional marketing agency. The pfSense firewall runs a captive portal for patient and visitor Wi-Fi. A LibreNMS virtual machine watches the switches. An old departmental application runs on an IIS server that someone set up years ago with PHP under FastCGI. That hospital has at least four PHP footprints, and the IT team directly controls only some of them.
Here are the usual suspects worth checking:
Firewall and network appliance management interfaces. pfSense and OPNsense both use PHP for their web interfaces and captive portals, and both have shipped fixes (details below). Palo Alto Networks has published an advisory confirming that PAN-OS 12.2, 12.1, 11.2, 11.1, and 10.2, along with Panorama, are affected, rated CVSS 8.7, and as of this writing no fixed release is available. If you run a Palo Alto at the edge, the management interface should not be reachable from the internet, period. This week is the week to confirm that.
Guest Wi-Fi captive portals. This one deserves its own line because it is easy to miss. A captive portal is, by design, reachable by untrusted devices. Anyone sitting in your waiting room or parking lot can talk to it. Netgate specifically tells captive portal users to update PHP as soon as possible, even though pfSense's management GUI is restricted to the LAN by default.
IT tools that are quietly built on PHP. LibreNMS, Cacti, the Zabbix web frontend, GLPI, osTicket, phpMyAdmin, Nextcloud, and Roundcube are all PHP applications. Smaller IT shops lean on these because they are free and capable. Most live on internal networks, which lowers the urgency, but "internal" is not the same as "safe." An attacker with a foothold on a workstation can reach them too.
Your public website. If it runs WordPress, Drupal, or Joomla, it runs PHP. Updating WordPress core and plugins does not fix this. The fix lives at the server level, below the CMS. If a vendor hosts the site, they own the patch, and you need to ask them directly (more on that below).
Windows servers running PHP under IIS. PHP on Windows typically runs as php-cgi.exe under IIS FastCGI. The CGI interface is in scope. These installs are usually unzipped into a folder rather than installed through Windows Installer, so they often do not show up in Programs and Features or in standard software inventory.
Vendor appliances and bundled software. NAS management consoles, building-management systems, and assorted vendor appliances embed PHP more often than their documentation admits. The Dutch NCSC maintains a community inventory of software with PHP dependencies. It is incomplete and still growing, but it is the best single place to check a product you are unsure about.
What to Do, in Order
The PHP project is blunt about this: there are no complete mitigations, and updating is the only safe choice. Everything below follows from that.
1. Build the list, starting with anything internet-facing or reachable by untrusted clients. The UK NCSC advises not limiting the search to old versions, because all versions may be affected. Internet-facing systems and captive portals go first, then internal systems.
On Windows servers, a quick sweep for PHP binaries will find the installs that software inventory misses. The script below reads the version from each file's metadata rather than executing it, then compares it against the fixed releases. If you run Configuration Manager, the same logic can be deployed as a script or adapted into a configuration item to sweep the whole server fleet.
Function Test-PHPVersionFixed ($VersionString) {
if ([string]::IsNullOrWhiteSpace($VersionString)) {
return "Unknown"
}
try {
$Version = [version]$VersionString
}
catch {
return "Unknown"
}
$Branch = "$($Version.Major).$($Version.Minor)"
switch ($Branch) {
"8.5" { if ($Version.Build -ge 12) { return "Fixed" } else { return "VULNERABLE" } }
"8.4" { if ($Version.Build -ge 27) { return "Fixed" } else { return "VULNERABLE" } }
"8.3" { if ($Version.Build -ge 36) { return "Fixed" } else { return "VULNERABLE" } }
"8.2" { if ($Version.Build -ge 35) { return "Fixed" } else { return "VULNERABLE" } }
default { return "VULNERABLE (end of life branch)" }
}
}
Function Find-PHPInstallations ($SearchRoots) {
foreach ($Root in $SearchRoots) {
$Files = Get-ChildItem -Path $Root -Recurse -File -Include "php.exe", "php-cgi.exe" -ErrorAction SilentlyContinue
foreach ($File in $Files) {
$ProductVersion = $File.VersionInfo.ProductVersion
$Status = Test-PHPVersionFixed -VersionString $ProductVersion
Write-Output "$($env:COMPUTERNAME) | $($File.FullName) | $($ProductVersion) | $($Status)"
}
}
}
Find-PHPInstallations -SearchRoots @("C:\", "D:\")
Official Windows builds from php.net carry a version in the file metadata, but a vendor-repackaged or custom-compiled binary may not. The script reports those as "Unknown" rather than guessing. For any "Unknown" result, confirm the version on that server by running the binary with -v.
On Linux, check what the web server is actually loading, not just what php -v reports at the command line. The CLI binary and the Apache module or PHP-FPM service can be different packages.
2. Update to a fixed release and restart every PHP worker. The fixed upstream versions are PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Linux distributions received the patches in advance, so check your distribution's package manager first. Two traps to watch for. First, distribution packages often backport fixes without changing the upstream version number, so a server reporting 8.1.x may be patched or may not be. Confirm against your distribution's security advisory, not the version string. Second, installing the package does not help until the running processes are replaced. Restart PHP-FPM, Apache, or IIS, then verify.
For the firewall platforms mentioned above:
- pfSense: Netgate lists pfSense Plus 26.07 and 26.03.1 and pfSense CE 2.9.0 as carrying PHP 8.5.12, and pfSense CE 2.8.1 as carrying PHP 8.3.36. Netgate notes the update cannot be run from the web GUI and must be done from SSH or the console. Plan accordingly if you were going to click through it remotely.
- OPNsense: Community Edition 26.7.7 and Business Edition 26.4.2p3 carry the fix. The OPNsense team advises restarting the captive portal service after updating.
- Palo Alto PAN-OS and Panorama: No fixed release yet, and as of this writing the advisory lists the fix timeline for every branch as "TBD." Palo Alto says it is not aware of malicious exploitation against its products. The primary defense is to restrict management interface access to trusted internal addresses or a single jump host. Threat Prevention subscribers can also enable Threat IDs 543004 and 97622 through 97625 (content version 9162 or later). Those signatures only cover the management interface if management traffic is routed through a dataplane interface and decrypted for inspection, so treat them as a secondary measure and not a substitute for locking down access. Watch the advisory for fixed versions.
3. If you cannot update right away, apply the temporary mitigations, and treat them as temporary. PHP lists configuration changes that reduce exposure to specific attack paths but do not make an installation safe. The two most useful:
- Set
session.upload_progress.enabled=0in php.ini, the FPM pool configuration, or the web server configuration. PHP warns not to rely onini_set()or.user.inifor this. Restart every worker afterward. This blocks a confirmed attack path that is enabled by default and does not require the application to use sessions at all. - On PHP 8.5, also set
fatal_error_backtraces=0and restart.
PHP also lists memory and request-size settings for CVE-2026-109618, and specifically warns against using RLIMIT_AS or RLIMIT_DATA as a control, because those limits trigger the vulnerable code path rather than preventing it. If an application does not accept file uploads, blocking multipart requests at a reverse proxy or WAF is a reasonable stopgap.
One more reason to leave upload progress turned off even after you patch: on October 23, PHP published an informational notice about a related issue, CVE-2026-115560, that the October 21 releases do not fix. It only applies in an unusual configuration where an application switches its session serializer at runtime, and PHP considers that combination unlikely in practice. A fix is expected in PHP's next regular release. The interim guidance is the same setting. If nothing on the server uses upload progress, there is no reason to turn it back on.
4. If you can neither patch nor mitigate, take it off the internet. The UK NCSC's guidance is direct: take the system offline if fixes or mitigations cannot be applied quickly. For a public website, a temporary maintenance page is a lot cheaper than a compromised server.
5. Look back to October 17, not October 21. Amazon recommends starting investigations from the earliest known exploitation date of October 17. Things worth searching for in web server, proxy, and WAF logs include POST requests containing PHP_SESSION_UPLOAD_PROGRESS, multipart uploads to pages that never normally receive uploads, unusually large or header-heavy request bodies, and bursts of HTTP 500 errors. On the host, look for memory-limit errors and worker crashes, new or modified files in the web root, unexpected scheduled tasks, processes spawned by the web server, and outbound connections from web server processes. Beazley Security's advisory has a solid detection checklist if you want a more complete list.
Two cautions. The vulnerabilities can also leak memory from other requests, so if a system was exposed and unpatched and you find anything suspicious, treat the passwords, API keys, and database credentials that system uses as compromised and rotate them. And if you are not confident in your own assessment of a system that holds patient data, bring in incident response help sooner rather than later. That is not a knock on anyone's skills. It is a recognition that a two-person IT team also has a hospital to keep running.
6. Ask your vendors directly. Do not wait for an email that may never come. Ask your web host or marketing agency what PHP version your site runs on and whether it has been patched and restarted. Ask how long they keep web server logs, because shared hosting plans often keep them for only days, and you may need them. Ask appliance vendors whether their products embed PHP and when a fix is coming. Get the answers in writing.
7. Plan your next PHP upgrade now. PHP 8.2 reaches end of life on December 31, 2026. PHP 8.1 and older already receive nothing from the PHP project, and the PHP security team provided only minimal source backports for 7.4, 8.0, and 8.1 this time. For context on how common that problem is, Shodan banner counts relayed by CybelAngel found about 2.24 million internet-facing PHP hosts, and roughly 59 percent of the ones that reported a version were on branches with no official fix. That count includes systems where a distribution may have backported the fix, so treat it as a rough indicator, not a precise measurement. Still, if any of your systems are on an end-of-life branch, this event is your business case for the upgrade.
The HIPAA Angle
Most of this is plain security hygiene, but a few HIPAA Security Rule requirements apply directly, and the documentation trail matters.
Start with the definition. Under 45 CFR 164.304, a security incident includes the attempted or successful unauthorized access, use, disclosure, modification, or destruction of information, or interference with system operations. Attempted is part of the definition. Your security incident procedures should already explain how routine, unsuccessful attempts are documented. If they don't, write that down now, because there will be a lot of attempts in your logs.
The Response and reporting implementation specification at 45 CFR 164.308(a)(6)(ii) is Required. It calls for identifying and responding to suspected or known security incidents, mitigating harmful effects to the extent practicable, and documenting incidents and their outcomes. Your PHP2Shell inventory, patch dates, mitigation decisions, and log review results are that documentation. Keep them.
The Information system activity review specification at 45 CFR 164.308(a)(1)(ii)(D) is also Required, and the Audit controls standard at 45 CFR 164.312(b) requires mechanisms that record and examine activity in systems that contain or use ePHI. If the logs for an ePHI system don't go back to October 17, that is a finding worth recording in your risk analysis and addressing through risk management, both Required.
Here is the hidden problem worth checking. Many organizations think of their public website as having nothing to do with HIPAA. But if the site has online forms that collect patient information, such as appointment requests or prescription refill requests, the site is very likely creating or receiving PHI. It belongs in your risk analysis like any other system that handles patient data, and the agency hosting it may be acting as a business associate. Under 45 CFR 164.314(a)(2)(i)(C), the business associate contract must require the business associate to report any security incident it becomes aware of to the covered entity. Confirm that you have a business associate agreement in place, and ask the question anyway.
Finally, if you find evidence that a system holding PHI was actually compromised, the breach rules come into play. Under 45 CFR 164.402, an impermissible access or disclosure is presumed to be a breach unless a risk assessment demonstrates a low probability that the PHI was compromised. Code execution on a server that stores or processes PHI is exactly the kind of event that needs that assessment. Follow your incident response and breach notification procedures, and involve counsel.
The Bottom Line
PHP2Shell is serious, but it is also very fixable. The work is mostly inventory and patching, and the hardest part is finding all the places PHP lives, especially the ones someone else manages for you. Start with anything an untrusted device can reach, including guest Wi-Fi. Patch and restart. Use the configuration mitigations only as a bridge. Look back to October 17. Write down what you did.
If your inventory turns up PHP in places you didn't expect, you are almost certainly not alone. What matters is what you do with that list.
This article is for informational purposes only and does not constitute legal or compliance advice. Covered entities and business associates should consult qualified legal counsel or compliance professionals before making decisions pertaining to HIPAA or IT infrastructure.
Sources
- PHP Project, News Archive 2026 (October 20 pre-announcement, October 21 security release, October 23 informational advisory): https://www.php.net/archive/2026.php
- PHP Security Advisory GHSA-w8hw-w9fx-j79w, "RCE via OOM corruption" (CVE-2026-109618): https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
- PHP Security Advisory GHSA-6wmf-4rv5-p3rp, "RCE via stale global state" (CVE-2026-109619): https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
- Amazon Web Services Security Blog, "Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot": https://aws.amazon.com/blogs/security/amazon-threat-intelligence-identifies-php2shell-exploitation-prior-to-public-disclosure-in-madpot/
- UK National Cyber Security Centre, "Critical security issue affecting PHP": https://www.ncsc.gov.uk/news/critical-security-issue-affecting-php
- NCSC-NL, PHP2Shell operational repository and software inventory: https://github.com/NCSC-NL/php2shell
- watchTowr, PHP2Shell FAQ: https://watchtowr.com/intelligence/php-cve-2026-109618-faq/
- Beazley Security Labs, Advisory BSL-A1233: https://labs.beazley.security/advisories/BSL-A1233
- The Next Web, "Millions of PHP2Shell attempts so far, but officials see no break-in": https://thenextweb.com/news/php2shell-millions-exploit-attempts-no-confirmed-breaches
- SecurityWeek, "PHP2Shell Patches Land as First Exploitation Attempts Hit Sensors": https://www.securityweek.com/php2shell-patches-land-as-first-exploitation-attempts-hit-sensors/amp/
- Netgate, "Critical PHP Security Update": https://www.netgate.com/blog/critical-php-security-update
- OPNsense Forum, "PHP2Shell (CVE-2026-109618 en CVE-2026-109619): OPNsense 26.7.7 / 26.4.2p3": https://forum.opnsense.org/index.php?topic=53191.0
- Palo Alto Networks Security Advisory, "Impact of Critical Vulnerabilities in PHP (CVE-2026-109618, CVE-2026-109619) on Palo Alto Networks Products": https://security.paloaltonetworks.com/CVE-2026-109618
- Threat Frontier, "PHP2Shell CVE-2026-109618: Patch PHP; PAN-OS Waits": https://threatfrontier.com/articles/php2shell-cve-2026-109618-cve-2026-109619-php-rce-pan-os-expressway
- Lilting, "PHP CVE-2026-115560 only hits apps that switch serialize_handler to php at runtime": https://lilting.ch/en/articles/php-cve-2026-115560-serialize-handler
- CybelAngel, "2.24M Internet-Facing PHP Hosts, 59% on Versions With No Fix Coming": https://cybelangel.com/blog/critical-php-rce-vulnerabilities-cve-2026-109618-and-cve-2026-109619/
- 45 CFR 164.304, Definitions: https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164/subpart-C/section-164.304
- 45 CFR 164.308, Administrative safeguards: https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164/subpart-C/section-164.308
- 45 CFR 164.312, Technical safeguards: https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164/subpart-C/section-164.312
- 45 CFR 164.314, Organizational requirements: https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164/subpart-C/section-164.314
- 45 CFR 164.402, Definitions (Breach Notification): https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164/subpart-D/section-164.402