Is PHP Quietly Running on Your ColdFusion Server? Check, and Remove It


If you run ColdFusion or Lucee on a Windows server with IIS, and you’ve got by no means put in PHP on objective, this one’s for you. There’s a very good probability PHP is in your server. It could also be left behind by a management panel, a phpMyAdmin set up from years in the past, or your host’s setup picture. Here’s find out how to discover out in a couple of minutes with PowerShell, and find out how to take away it safely if nothing makes use of it.

I bear in mind after I may go years with out making use of a safety repair. Now it seems like I’m chasing one thing down each few weeks: a patch right here, a mitigation there, a bot hammering a web page that should not exist. Such is life within the AI period, sigh. 

While I used to be signing in to my take a look at weblog the opposite day, the admin web page refused me with a plain IIS error: 403 Forbidden, and a message saying multipart form-data requests have been blocked by a PHP mitigation. My blogs are ColdFusion. They do not run a single line of PHP. So why was a PHP safety rule stopping me from signing in?


What occurred


The timing wasn’t a coincidence. On October 21, 2026, PHP shipped emergency patches for 2 essential flaws that allow an unauthenticated request run code on the server, nicknamed PHP2Shell. Every PHP setup that serves internet requests was affected: PHP-FPM, Apache’s mod_php, php-cgi, FrankenPHP and LiteSpeed. The repair is to put in a brand new model of PHP (8.5.12, 8.4.27, 8.3.36 or 8.2.35).

My internet hosting firm responded the identical week with an internet server safety rule. The rule lived in IIS’s server-wide URL Rewrite guidelines, so it utilized to each web site on the server and blocked each request whose content material kind was multipart/form-data, whatever the deal with. That’s the encoding a browser makes use of for any kind that may add a file, and loads of varieties use it even after they do not.

PHP’s personal recommendation does not embody blocking these requests. It’s to patch, and till then to show off session.upload_progress.enabled and decrease post_max_size. Several of the official mitigations concern how PHP handles uploads, so I can see why a number would attain for the largest hammer. For a PHP web site that is a blunt however comprehensible defend. For my ColdFusion websites it meant the admin sign-in kind, each picture add and each file add failed on all 4 websites directly. The rule matched each deal with, not simply .php ones.

Once I’d scoped the rule to .php addresses (extra on that under), every part labored once more. Then I requested the plain query: why is PHP on this server in any respect? The reply was a phpMyAdmin set up I had requested for years in the past to handle one MySQL database. It was nonetheless there, nonetheless in a web site folder, and its login web page was open to the entire web. The host turned the blanket rule off as soon as I advised them PHP was not in use, and I went in search of the rest PHP had left behind.


Check 1: is IIS sending .php information to PHP?


IIS solely runs PHP if a handler mapping tells it to. Open PowerShell as Administrator on the server:

Import-Module WebAdministration
Get-WebHandler -PSPath 'IIS:\Sites' | Where-Object { $_.path -like '*.php' } | Select-Object identify, path, scriptProcessor

If it prints nothing, IIS does not run PHP. If it prints one thing like this, it does, for each web site that inherits the server’s settings:

identify    path  scriptProcessor
----    ----  ---------------
FastCGI *.php C:\php\php-cgi.exe

Note the handler’s identify and the scriptProcessor path. You’ll want each in case you take away it.


Check 2: are there any PHP information in your websites?


PowerShell’s Get-BabyItem -Recurse works, however on a server with years of uploaded photos it might crawl for minutes. Windows’ personal dir is far quicker. This counts the PHP information beneath your internet root:

cmd /c "dir C:\inetpub\wwwroot\*.php /s /b" 2>$null | Measure-Object | Select-Object Count

If the depend is not zero, this exhibits which folders they’re in, busiest first:

cmd /c "dir C:\inetpub\wwwroot\*.php /s /b" 2>$null | ForEvery-Object { Split-Path $_ -Parent } | Group-Object | Sort-Object Count -Descending | Select-Object -First 25 Count, Name | Format-Table -AutoSize

Mine discovered about 4,500 information in two folders, each phpMyAdmin: one inside a web site, and a second copy on the internet root, which IIS’s Default Web Site served to anybody who visited the server’s naked IP deal with.

If you discover PHP information you do not acknowledge, particularly scattered via picture or add folders, or modified not too long ago, cease and deal with it as a potential break-in. Attackers love dropping small PHP “internet shells” into add folders. This lists probably the most not too long ago modified ones:

cmd /c "dir C:\inetpub\wwwroot\*.php /s /b" 2>$null | Get-Item | Sort-Object LastWriteTime -Descending | Select-Object -First 15 LastWriteTime, Length, FullName | Format-Table -AutoSize

Check 3: is PHP put in or working?


Get-Process php* -ErrorAction SilentlyContinue | Select-Object Name, Id, StartTime
Test-Path C:\php

No php-cgi.exe course of simply means nothing has requested for a PHP web page not too long ago. IIS begins it on demand. The handler from Check 1 is what issues.


Check 4: what can the web see?


From any pc, strive the same old addresses on your individual websites:

foreach ($path in "phpmyadmin/", "phpMyAdmin/", "pma/", "information.php") {
    $url = "https://www.mysite.com/$path"
    strive { $r = Invoke-WebRequest $url -UseBasicParsing -TimeoutSec 15; "$($r.StatusCode) $url" }
    catch { "$($_.Exception.Response.StatusCode.value__) $url" }
}

Anything that solutions 200 deserves a glance. A phpMyAdmin login web page dealing with the web is a standing invitation: bots strive passwords on all of it day, and each try begins PHP and talks to your database.


Removing it safely


Do these so as, and again up first. Every step is reversible.

1. Back up IIS’s configuration

IIS can snapshot its personal configuration and restore it in a single command:

& "$env:windir\System32\inetsrv\appcmd.exe" add backup "before-php-removal"

To undo every part under: appcmd.exe restore backup "before-php-removal".

2. Move phpMyAdmin (and some other PHP app) out of the online folders

Move, do not delete. Its configuration file could maintain a database password, so preserve it someplace non-public for a number of weeks in case one thing seems to want it:

New-Item -ItemSort Directory -Force C:\Temp\removed-php | Out-Null
Move-Item C:\inetpub\wwwroot\mysite\phpmyadmin C:\Temp\removed-php\phpmyadmin-mysite

If Move-Item complains {that a} file is in use, PHP has it open. iisreset /cease, transfer it, then iisreset /begin. (Your websites are down for a number of seconds.) And if it says “Could not discover part of the trail”, it is the vacation spot folder that is lacking, not the supply. That one fooled me.

For managing MySQL afterwards, a desktop instrument on the server over Remote Desktop, like HeidiSQL or MySQL Workbench, does every part phpMyAdmin did with no public login web page.

3. Block .php on the door

IIS’s request filtering can flip away a file extension earlier than any handler sees it. Added on the server stage, it covers each web site:

Add-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/safety/requestFiltering/fileExtensions' -Name '.' -Value @{ fileExtension = '.php'; allowed = 'false' }

Now any .php deal with will get “404 – the request filtering module is configured to disclaim the file extension”, whether or not the file exists or not.

4. Remove the handler and the FastCGI entry

Use the handler identify from Check 1 (mine was FastCGI) and the php-cgi.exe path:

Remove-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/handlers' -Name '.' -AtElement @{ identify="FastCGI" }
Remove-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/fastCgi' -Name '.' -AtElement @{ fullPath="C:\php\php-cgi.exe" }

Run Check 1 once more. It ought to print nothing.

5. Uninstall PHP, final

If PHP got here from an installer, take away it beneath Apps > Installed apps. If it is only a folder like C:\php, rename it to C:\php-removed for a number of weeks earlier than deleting it. If something complains, you may know instantly, and it is one rename to place again.

If PHP was put in by your host, ask them earlier than step 5. Their personal monitoring scripts are unlikely to want it, however it’s their set up.


If you should preserve a rule like this


Maybe you do run PHP someplace, or your host needs their rule. Then scope it to PHP addresses as an alternative of each deal with. The rule’s was the entire downside. This modifications it to .php addresses solely, leaving ColdFusion’s varieties alone (use the rule’s personal identify):

Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter "system.webServer/rewrite/globalRules/rule[@name="PHP Mitigation"]/match" -Name url -Value '\.php($|/)'

Note the only quotes across the sample. I first tried the identical change with appcmd.exe, and PowerShell quietly mangled the quoting: no error, and no change both. Set-WebConfigurationProperty with single quotes did it on the primary strive. Check the outcome with Select-String on C:\Windows\System32\inetsrv\config\applicationHost.config.


Lucee on Linux and Apache


The similar questions, totally different instructions:

php -v                          ## is the PHP command-line put in?
apachectl -M | grep -i php      ## is Apache working PHP (php_module, proxy_fcgi to php-fpm)?
discover /var/www /residence -name "*.php" 2>/dev/null | head -50

On Debian and Ubuntu, sudo a2dismod php8.3 (your model) and sudo systemctl restart apache2 cease Apache from working PHP. Then take away the packages together with your package deal supervisor when you’re positive nothing wants them. Control panels resembling Virtualmin usually set up PHP for their very own instruments, so examine earlier than uninstalling.


Gotchas


  • A server-wide rule catches each web site. A rule written for PHP blocked my ColdFusion sign-ins and uploads. If a 403 seems out of nowhere, learn the total IIS error web page; mine named the rule.
  • Hosts re-run their scripts. Mine recreated its rule on each run, so a neighborhood repair may have been undone silently. Tell your host what you modified and why.
  • A config edit can land within the flawed internet.config. My first repair went right into a web site’s internet.config, and nothing modified. A fast Select-String on the file IIS truly reads would have saved me ten minutes.
  • Trusted Cache hides your fixes. If you exchange a .cfm by hand whereas diagnosing, ColdFusion retains working the previous compiled copy till you clear it. A brand-new file identify is the short workaround.
  • Removing PHP is not an alternative choice to patching. If you do run PHP, replace it now to eight.5.12, 8.4.27, 8.3.36 or 8.2.35 (or newer), and set session.upload_progress.enabled = 0 in php.ini till you possibly can. PHP 8.1 and older not get updates from the PHP challenge. Removing PHP is barely the best reply when nothing makes use of it.

Further Reading


This entry was posted on October 23, 2026 at 11:39 PM and has obtained 7464 views.

There are 0 feedback.



Source link