The Qualys post describes scripts in its own product, TruRisk Eliminate, that automate this upgrade. That's a vendor announcement and this article treats it as one. The problem it describes applies to anyone running PHP on IIS, Apache for Windows, XAMPP, WampServer or Homebrew, whether or not they use Qualys.
The vulnerability: why this one matters
Based on the NCSC-NL tracking repository, on 21 October 2026, PHP published fixed releases for CVE-2026-109618 and CVE-2026-109619: PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. The same repository summarises PHP's descriptions: CVE-2026-109618 is remote code execution via out-of-memory corruption during request cleanup, and CVE-2026-109619 is remote code execution via stale request-owned global state reused by a later request on the same worker.
Red Hat's security bulletin (RHSB-2026-013) calls both memory-corruption flaws in PHP request handling. It says an unauthenticated remote attacker could trigger memory corruption and possibly run arbitrary code. Red Hat also adds some useful caveats:
- Reliable exploitation needs precise heap manipulation and timing.
- On RHEL 8 and later, the default PHP-FPM setup makes remote code execution hard in practice. Default mod_php setups are at higher risk.
- Systems that don't have PHP installed, or don't expose it to untrusted HTTP requests, are not affected.
Those judgements are about Red Hat's own default configurations. They don't promise anything about a Windows IIS box or a Mac mini in a build lab.
The threat isn't theoretical. According to SOCRadar, the flaws were added to CISA's KEV catalog on October 26, 2026 (FCEB due date: October 29, 2026). SOCRadar also reports that Unit 42 reported post-exploitation activity it initially linked to PHP2Shell, describing an intrusion at a European government agency run through a vulnerable PHP application. Several public GitHub repositories now advertise proof-of-concept exploit tooling. If you were waiting for a sign before patching, this is it.
A third issue is being tracked alongside these two. Red Hat notes that on October 23 the PHP project published an informational advisory for CVE-2026-115560, also in the session upload progress feature. PHP calls it an unlikely remote code execution path that needs an unusual mix of configuration and application code, and it will be fixed in a routine release rather than an emergency one.
Section summary: PHP2Shell is two critical, unauthenticated RCE flaws, fixed upstream in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. They are reportedly being exploited and are on CISA's KEV list. How exposed you are depends on your deployment, but internet-facing PHP should be treated as urgent.
Why Windows and macOS are harder to fix
Qualys explains the problem by platform.
Windows. There is no Microsoft-provided PHP and no official PHP installer or in-place updater. The official builds on downloads.php.net are plain ZIP archives in several variants:
- Thread Safe (TS) or Non-Thread Safe (NTS)
- x64 or x86
- Different Visual Studio compiler builds
A manual upgrade means picking the matching build, stopping IIS or Apache, replacing the binaries while keeping php.ini and any custom extensions, and then restarting services. Third-party stacks such as XAMPP, WampServer, Laragon, Chocolatey and Scoop each use their own folder layout. A single server can end up with several PHP copies, and only one of them is on PATH.
macOS. Qualys notes that Apple removed PHP in macOS Monterey (12.0), so Apple updates never touch it. php.net publishes only source code for macOS. On modern Macs, PHP usually comes from Homebrew, either the php formula or a versioned [email][email protected][/email] formula. MacPorts, MAMP and hand-compiled builds also exist.
The result: a vulnerability scanner flags the host, and the OS patch catalog has nothing to deploy. As Qualys puts it, the vulnerability is real but the fix isn't a patch.
Section summary: On Windows and macOS, PHP sits outside the OS update system. Fixing PHP2Shell there means finding every PHP installation and upgrading each one in place.
What the Qualys scripts do (vendor-reported)
Qualys says its Threat Research Unit has added scripts to the Custom Assessment and Remediation (CAR) library in TruRisk Eliminate. Customers can find them by searching for "PHP Update to Latest Patch Version" in the PHP2Shell category. Both the Windows and macOS scripts follow two rules:
- They stay within the installed minor series. Qualys gives 8.2.33 moving to the latest 8.2.x as its example, and says the scripts never jump a major or minor version. Applications keep running on the branch they were tested on.
- They stop on end-of-life branches. If the installed series is no longer published, the script reports that and stops rather than guessing. Qualys then points customers to a separate PHP2Shell mitigation script, which makes configuration changes and restarts services. Qualys is clear that this lowers the risk but doesn't replace the upgrade.
The minor-series rule is sensible, but it isn't the whole story. SOCRadar's version table lists 8.2 as security fixes only until December 31, 2026. Patching 8.2 today buys you about eight weeks before you need a branch migration anyway.
On Windows
The behaviour Qualys describes covers most of the traps in a manual upgrade:
- Finding every PHP copy. The script checks machine and per-user PATH entries, common folders (C:\php*, XAMPP, WAMP, Laragon, Program Files, Scoop), IIS FastCGI handlers in
applicationHost.config, and any Windows service that launches a PHP binary. - Matching the build. It asks
php.exefor its build variant (TS/NTS, x64/x86, VC15/VS16/VS17) and picks the matching official build from PHP'sreleases.json. - Using the machine proxy. It uses the machine-wide WinHTTP proxy, because the SYSTEM account has no per-user proxy settings. That's a common reason automated downloads fail in locked-down networks.
- Checking the download. It verifies the ZIP's SHA256 hash against the published value before changing anything.
- Swapping the files. It stops IIS (W3SVC/WAS), Apache and any php/php-cgi processes using that folder, backs up the whole PHP folder, and copies the new binaries over the old ones. php.ini and extra extensions are kept. It then runs
php.exeto confirm the new version. - Rolling back. If the version check fails, it restores the backup and restarts services.
On macOS
- It follows symlinks into the Homebrew Cellar to find out whether
phpor a[email][email protected][/email]formula owns the active binary. Installations from MacPorts, MAMP or manual builds are reported and left alone. - CAR runs as root, but Homebrew refuses to run as root. The script therefore runs brew as the user who owns the Homebrew installation. It also fixes any Homebrew files left owned by root from earlier runs.
- It retries when it hits "another brew update is already running" and falls back to cached formula data if the refresh fails.
- If the default
phpformula has moved to a newer series, it installs or upgrades the matching versioned formula and relinks thephpcommand, rather than jumping a major version. - It restarts php-fpm through
brew servicesif php-fpm was running before, and printsphp -vin the job output.
In Qualys's sample output, a macOS host goes from 8.2.33 to 8.2.35 with [email][email protected][/email] relinked as the active PHP. 8.2.35 is the upstream fixed release for that branch.
Section summary: Qualys says its scripts find every PHP installation, match the build, verify the download, back up, upgrade within the same series and roll back on failure. These are the vendor's claims, not independent test results.
Agent or agentless: what you need
The same script content can reach hosts in two ways:
| Delivery mode | How it runs | Requirements |
|---|---|---|
| Agent Devices | Locally, through the installed Qualys Cloud Agent | Cloud Agent on the host |
| Perimeter Devices | Through an authenticated Qualys scanner, with no agent | A scanner that can reach the host, plus Windows or SSH credentials with rights to stop services and replace PHP binaries |
The agentless option matters because many exposed PHP servers are hard to put agents on. Qualys gives examples: a DMZ Windows Server running a vendor web app on IIS and PHP, or Mac minis in an engineering build lab. "Agentless" still means remote code execution with privileged credentials, though, so expect your change-control board to ask about that.
The workflow Qualys describes:
- In ETM, find the Windows and macOS hosts flagged for CVE-2026-109618 and CVE-2026-109619, and tag them by platform.
- In CAR, import the matching script and choose Agent Devices or Perimeter Devices, plus Windows or Mac. For agentless runs, point the job at a scanner appliance that can reach the hosts, with the right authentication records.
- Run the job during a maintenance window, because IIS, Apache or php-fpm will restart.
- Check the job output for before and after versions. On Windows the log also lists the installations found, the build variant, the hash check, the services restarted and the backup folder location.
- Rescan and confirm the vulnerability finding (QID) has cleared. A successful job on its own doesn't prove the host is no longer exposed.
If you're not a Qualys customer
The problem is the same without the product. Some practical points, based on the sources above:
- Look for every PHP copy, not just the one on PATH. IIS FastCGI mappings and bundled stacks like XAMPP are easy to miss. Appliances and vendor products often bundle PHP too. The NCSC-NL repository tracks vendor status for products from Cisco, Broadcom, NetApp and others.
- Check what the web server actually runs. Red Hat warns that
php -ireports the command-line configuration. It recommends a temporaryphpinfo()page to confirm the settings the web server is using. - Upgrade to the fixed release for your branch: 8.5.12, 8.4.27, 8.3.36 or 8.2.35. Unofficial EOL backports exist on GitHub, but you can't vouch for how they were built. Moving to a supported branch is the safer route.
- Treat mitigations as temporary. Microsoft's Azure Network Security blog advises customers to upgrade PHP and describes Azure WAF rules as an extra layer, not a replacement. Red Hat says much the same about configuration changes such as disabling
session.upload_progress.enabled, which can break workloads and only partly block the vulnerable code paths. Red Hat also says to fully restart PHP workers after any change, because a reload isn't enough.
The bottom line
Qualys is selling something, but its main point holds: "patched" depends on a patch existing in your catalog. For PHP on Windows and macOS, no such patch exists. The fix is an upgrade you have to plan, test, run and then confirm with a rescan. With KEV listing, public exploit tooling and reported intrusions, upgrade internet-facing PHP hosts first. Then plan migrations off 8.2 before its December 31 end of support.
References
- PHP2Shell CVE-2026-109618 & 109619: Affected Versions & Fix socradar.io
- PHP2Shell on Windows and macOS: Fix Without a Patch - Qualys Qualys · 2026-11-04T09:20:32+00:00
- Addressing PHP2Shell CVE-2026-109618 and CVE-2026-109619: upgrade guidance and Azure WAF mitigations | Microsoft Community Hub techcommunity.microsoft.com