Discover, remediate, and verify vulnerable PHP installations on Windows through a single automated workflow

Modified on Fri, 30 Oct at 12:37 PM

The fix is straightforward: upgrade to a secure PHP version. The challenge is finding and updating every installation.

Unlike Linux, where PHP is commonly managed through package managers, Windows deployments frequently rely on manually extracted binaries, IIS or Apache integrations, and bundled environments such as XAMPP, WAMP, and Laragon.

These deployments may lack centralized update mechanisms, making comprehensive vulnerability remediation difficult.

What Makes SecPod's Custom Patch Different?

Capability

What it does

Comprehensive discovery

Searches drives, PATH, registry, IIS, Apache, services, scheduled tasks, and supported development stacks, including Chocolatey and Scoop shims

Intelligent build selection

Identifies the installed PHP branch, Thread Safe (TS) or Non-Thread Safe (NTS) configuration, and x86/x64 architecture to select the matching build

Automatic version targeting

Retrieves the latest available official release for the applicable PHP branch at execution time

Trusted update sources

Downloads official PHP Windows packages and verifies SHA-256 checksums

Configuration preservation

Saves existing php.ini files and restores them after binary replacement

Service-aware remediation

Identifies and temporarily stops dependent services, IIS application pools, Apache processes, and scheduled tasks before restarting the components stopped by the patch

Discovery and verification modes

Supports inventory-only discovery and post-remediation version compliance checks

How the Patch Works

The patch follows a five-stage automated workflow:

  • Discover: Identify PHP installations across supported filesystem locations and application integrations.
  • Assess: Check installed versions, architecture, and build variants against secure releases.
  • Prepare: Download and validate the appropriate PHP package, preserve configuration, and identify dependent processes.
  • Remediate: Replace vulnerable binaries with fixed versions and restart affected services.
  • Verify: Confirm updated PHP versions and report installations that require further attention.


Version-Aware Updates

The patch preserves the existing PHP branch for supported releases, upgrading to the latest available version within that branch.

Existing PHP branch

Minimum fixed version

Remediation

PHP 8.2

8.2.35

Latest 8.2.x

PHP 8.3

8.3.36

Latest 8.3.x

PHP 8.4

8.4.27

Latest 8.4.x

PHP 8.5

8.5.12

Latest 8.5.x

PHP 8.1 and earlier

No upstream fixed release

Upgrade to latest 8.5.x, subject to compatibility validation

The patch dynamically identifies new official releases instead of relying exclusively on hardcoded patch versions.

Important

Upgrading PHP 8.1 or earlier to PHP 8.5 may introduce breaking changes in applications, extensions, and configuration. Such upgrades require additional validation.

1. Check before you deploy

A few minutes of preparation here prevents an outage later.

  • Test in a lab first: run the patch on staging systems that mirror production and confirm your applications work.
  • Know your versions: run with -Mode Discover to list every PHP install and what will change. No changes are made.
  • Legacy PHP (below 8.2): the jump to 8.5 can break extensions, php.ini settings and code. Plan application testing or skip these installs.
  • Prerequisites: Windows PowerShell 5.1+, administrator rights, Visual C++ 2015-2022 Redistributable, and HTTPS access to windows.php.net (or a folder of official ZIPs via -PackageCache).
  • Take your own backup: the script saves and restores only php.ini files; it does not back up PHP binaries or roll back. Take a VM snapshot or file backup of the PHP folders first.
  • Maintenance window: PHP sites and jobs are briefly unavailable while binaries are swapped.



2. Deploy the patch

Saner customers (Saner PM custom remediation):

  1. Open PM: log in to the Saner web console, select the Account, click the Saner tools icon and choose PM (Patch Management).
  2. Missing Patches: click the Missing Patches tab on the navigation bar.
  3. Third-party view: uncheck OS so only Third Party patches are listed, then locate the PHP entries in the Asset column.
  4. Select PHP: tick the checkbox next to each PHP application to patch and click Apply Selected Patches. The Create Patching Task window opens.
  5. Name and schedule: enter a Task Name and choose a Remediation Schedule: Immediate, After scheduled scan, or Custom date (use your maintenance window).
  6. Upload the script: upload Remediate-PhpBinaries.ps1 as the Custom Patch file for each PHP application (.ps1 is supported for Windows).
  7. Confirm details: check the Patch Name, Version and Release Date, then click Confirm next to Release Date until a green tick appears.
  8. Create the task: click Apply Selected Patches. Saner PM runs the script on the selected endpoints at the scheduled time.

Full walkthrough with screenshots: How to perform custom remediation for applications that require paid patches using Saner PM


Manual or other tools: run from an elevated prompt, or push through SCCM, Intune or any tool that runs as SYSTEM:

powershell -ExecutionPolicy Bypass -File .\Remediate-PhpBinaries.ps1

Script options

Flag

Default

What it does

-Mode

Apply

Apply replaces binaries. Discover only lists installs and planned actions. Verify reports whether each install is on a fixed build (exit code 2 if not).

-AllowEolUpgrade

$true

Upgrades PHP older than 8.2 to the latest 8.5. Set to $false to skip those installs.

-Build

Auto

Detects Thread Safe or NTS from php.exe. TS or NTS forces a variant; refused if it does not match the install.

-Architecture

Auto

Detects x64 or x86 from php.exe. A forced value that does not match is refused.

-StopDependents

$true

Stops tasks, PHP services, IIS pools, Apache and PHP processes tied to the install. Apply will not run if $false.

-RestartDependents

$true

Restarts only what this run stopped, after a verified replacement.

-BackupRoot

ProgramData

Folder for logs, downloads and php.ini copies (default C:\ProgramData\PhpBinaryRemediation).

-PackageCache

None

Folder of pre-downloaded official ZIPs for offline systems. File name and SHA-256 must match.

Flags can be combined, for example -Mode Discover -AllowEolUpgrade:$false. The script's header comments describe each one in detail.



3. Validate before your site goes live

The script exiting is not the finish line. Before the site goes back live, confirm:

  • Compliance check: run with -Mode Verify. Exit code 0 means every install is on a fixed build; 2 means something needs attention.
  • Version: php -v shows the latest release of the branch, never below the minimums above.
  • Services: IIS application pools, Apache and PHP services are running again; restart any the log reports as failed to start.
  • Application: load key pages, log in, run critical transactions, and confirm scheduled PHP jobs complete.
  • Configuration: confirm your php.ini settings are intact and check the log under C:\ProgramData\PhpBinaryRemediation for missing modules or custom extensions.
  • Rescan: run a Saner vulnerability scan to confirm the CVE detections are cleared.

Caution

This patch replaces PHP binaries on live systems. Always validate on lab systems before production, then roll out to a pilot group before the wider estate. The script does not back up or roll back PHP binaries, so take a snapshot or backup before deploying. Only php.ini files are saved and restored. Not covered: Linux and macOS (use vendor updates), application code, Composer packages, custom PECL extensions, PHP in WSL, and PHP 8.6 or later.

Find it, patch it, verify it, and keep tracking every Windows host until Verify comes back clean.

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article