How Windows “Best‑Fit Mapping” Enables PHP‑CGI Remote Code Execution and How to Fix It
This article explains how Windows’ Best‑Fit Mapping can cause PHP‑CGI to misinterpret query‑string characters, allowing attackers to inject malicious parameters and execute arbitrary code, and provides detailed mitigation steps including version upgrades and Apache rewrite rules.
Description
On Windows, PHP 8.1.x (up to 8.1.29), 8.2.x (up to 8.2.20) and 8.3.x (up to 8.3.8) combined with Apache and the PHP‑CGI binary may be affected by the Win32 API “Best‑Fit” mapping. When a code page such as Traditional Chinese, Simplified Chinese or Japanese is active, non‑ASCII characters in the query string can be mapped to a hyphen (‑). The PHP‑CGI process interprets the resulting command‑line arguments as PHP options, allowing an attacker to inject options like allow_url_include=1 or auto_prepend_file=php://input. This can lead to source‑code disclosure or arbitrary PHP code execution.
When php_cgi runs on Windows with the mentioned code pages, a specially crafted query string can inject malicious parameters and achieve arbitrary code execution.
Attack Scenarios
Scenario 1: PHP running in CGI mode
Apache can map requests to the PHP‑CGI executable via AddHandler / Action or FilesMatch / SetHandler. The vulnerable configuration looks like:
AddHandler cgi-script .php
Action cgi-script "/cgi-bin/php-cgi.exe"or
<FilesMatch "\.php$">
SetHandler application/x-httpd-php-cgi
</FilesMatch>
Action application/x-httpd-php-cgi "/php-cgi/php-cgi.exe"Scenario 2: Exposing the PHP binary (default XAMPP configuration)
Even without explicit CGI mode, exposing php.exe or php-cgi.exe in a CGI‑accessible directory is vulnerable. A typical XAMPP setup uses:
ScriptAlias /php-cgi/ "C:/xampp/php/"Alert Details
Request routing
/php-cgi/php-cgi.exe?%ADd+allow_url_include%3D1+%ADd+auto_prepend_file%3Dphp://input
Request time: 2024-06-09 20:22:55Request error
Uncaught InvalidArgumentException: Malformed UTF-8 characters, possibly incorrectly encoded in /var/www/xxx/Json.php:50
#0 Json->output()
#1 Response->getContent()
#2 Error->appException() {main}Detailed error
/cgi-bin/php-cgi.exe?%ADd+allow_url_include%3D1+%ADd+auto_prepend_file%3Dphp://input
Malformed UTF-8 characters, possibly incorrectly encodedThe issue does not affect non‑Windows deployments, but malicious requests can trigger alerts and interface errors.
Affected PHP Versions
PHP 8.1.x up to 8.1.29
PHP 8.2.x up to 8.2.20
PHP 8.3.x up to 8.3.8
All PHP 7.4 releases
All PHP 7.3 releases
Mitigation
Upgrade to patched versions
PHP 8.1.29 or later
PHP 8.2.20 or later
PHP 8.3.8 or later
Temporary mitigation for non‑upgraded systems
For the affected locales, add a rewrite rule that blocks query strings beginning with the problematic byte ( %AD).
RewriteEngine On
RewriteCond %{QUERY_STRING} ^%ad [NC]
RewriteRule .? - [F,L]XAMPP for Windows users
If PHP‑CGI is not required, comment out the ScriptAlias line in httpd-xampp.conf to stop exposing the binary.
# ScriptAlias /php-cgi/ "C:/xampp/php/"References
PHP official fix PR: https://github.com/php/php-src/commit/b6d1d3980a664882f03021e9bb918089ed3dc428
PHP 8.3.8 ChangeLog: https://www.php.net/ChangeLog-8.php
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
