PHP powers approximately 80% of websites worldwide — WordPress, Drupal, Laravel, Symfony, and millions of custom applications. Vulnerabilities in the PHP engine itself, its extensions, or its configurations can expose millions of applications simultaneously.
CVE-2024-4577: RCE in PHP CGI (CVSS 9.8)
The PHP Zero-Day of 2024
In June 2024, CVE-2024-4577 — a remote code execution vulnerability in PHP CGI mode on Windows. A flaw in CGI parameter handling allowed an attacker to execute arbitrary commands by adding special arguments to the URL.
Windows only:
On Windows, the command-line argument processing engine can interpret certain encoded characters as argument delimiters. By exploiting Windows character conversion (\xad to -), an attacker can inject PHP parameters into the CGI request.
GET /index.php?%ADd+allow_url_include%3d1+%ADd+auto_prepend_file%3dphp://input HTTP/1.1
Content-Type: application/x-www-form-urlencoded
<?php system('whoami'); ?>
Affected versions: PHP 8.3.x < 8.3.8, 8.2.x < 8.2.20, 8.1.x < 8.1.29 (Windows CGI/FastCGI)
This CVE is actually a bypass of the patch for CVE-2012-1823 — a 12-year-old PHP CGI vulnerability that developers thought had been fixed.
CVE-2019-11043: RCE in php-fpm (CVSS 9.8)
A buffer underflow in php-fpm's request handler, combined with a misconfigured Nginx, enabled remote code execution.
Condition: Nginx configured with fastcgi_split_path_info and a vulnerable regex pointing to php-fpm.
# VULNERABLE Nginx configuration
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# ...
}
CVE-2018-19518: RCE via IMAP (CVSS 9.8)
A command injection in PHP's IMAP extension enabled system command execution via imap_open() with an attacker-controlled malicious IMAP server.
CVE-2016-7124: Unserialize Object Injection (CVSS 9.8)
A flaw in serialized object handling during unserialize() allowed creating objects of unintended types, leading to arbitrary code execution via "gadget chains" in PHP frameworks.
This CVE illustrates a structural PHP problem: unserialize() on untrusted data is dangerous in all PHP versions.
Dangerous PHP Configurations
Beyond engine CVEs, dangerous configurations expose millions of applications:
allow_url_fopen / allow_url_include
; DANGEROUS — allows include() from URLs
allow_url_include = On
; CORRECT
allow_url_include = Off
allow_url_fopen = Off ; if not needed
expose_php
; DANGEROUS — reveals PHP version in headers
expose_php = On
; CORRECT
expose_php = Off
Error reporting in production
; DANGEROUS in production — reveals paths and structure
display_errors = On
; CORRECT in production
display_errors = Off
log_errors = On
error_log = /var/log/php/errors.log
Securing PHP
1. Update to a Supported Version
# Check version
php --version
# Supported versions (late 2024)
# PHP 8.3 — supported until November 2026
# PHP 8.2 — supported until December 2025
# PHP 8.1 — supported until December 2024 (end of life)
# PHP 7.x, 5.x — no longer supported, vulnerable!
2. Configure php.ini Securely
; /etc/php/8.2/fpm/php.ini
expose_php = Off
display_errors = Off
log_errors = On
allow_url_include = Off
allow_url_fopen = Off
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
open_basedir = /var/www/html:/tmp
3. Use Strict Types
<?php
declare(strict_types=1);
// Forces type checking — reduces injection vectors
function processId(int $id): array {
// $id is guaranteed to be an integer
}
4. Validate and Sanitize All Input
// Validation
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
if ($id === false || $id === null) {
throw new InvalidArgumentException('Invalid ID');
}
// Prepared statements ONLY (never SQL concatenation)
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
5. Scan Composer Dependencies
# Run Composer security audit
composer audit
# Or use local-php-security-checker
local-php-security-checker --path=/var/www/html/composer.lock
PHP and Frameworks: Extended Attack Surface
PHP CVEs also impact popular frameworks and CMS:
- WordPress (PHP): hundreds of plugin CVEs
- Laravel: a few deserialization CVEs
- Drupal: Drupalgeddon (CVE-2018-7600, CVSS 9.8) — massively exploited RCE
Keeping PHP updated is necessary but insufficient — Composer dependencies and CMS must also be monitored.
Check PHP CVEs on cveo.tech — search for php to see all vulnerabilities referenced in the NVD.