CVE-2024-9026
Patch Available.
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
PHP is a general-purpose scripting language used mostly for web development. It runs behind web servers through server APIs such as Apache mod_php and PHP-FPM, and powers content management systems and frameworks such as WordPress, Drupal, Moodle and Laravel. PHP-FPM is PHP's FastCGI process manager: a master process that runs pools of worker processes and, when catch_workers_output is enabled, collects what the workers write to stdout and stderr into its own log.
An Improper Input Validation vulnerability (CVE-2024-9026) has been identified in the way the PHP-FPM master process reads worker output, which allows a script that can write chosen data to stderr to remove up to 4 characters from log messages or slip extra characters into them, and to remove more log data when PHP-FPM logs to syslog. PHP tracks this issue as GHSA-865w-9rf3-2wh5.
Per MITRE CWE-117: The product constructs a log message from external input, but it does not neutralize or incorrectly neutralizes special elements when the message is written to a log file.
This issue affects PHP 8.1 before 8.1.30, PHP 8.2 before 8.2.24 and PHP 8.3 before 8.3.12, as well as the End-of-Life release lines PHP 7.4 (from 7.4.4) and 8.0 through their final releases (7.4.33 and 8.0.30).
Details
Module Info
- Product: PHP
- Affected packages:
php-src(sapi/fpm) - Affected versions: >=7.4.4 <8.1.30, >=8.2.0 <8.2.24, >=8.3.0 <8.3.12
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 8.1.30, 8.2.24, 8.3.12
- NES for PHP 7.4.1 (based on PHP 7.4.33)
Vulnerability Info
This Low-severity vulnerability is found in the FPM SAPI of PHP 8.1 before 8.1.30, 8.2 before 8.2.24 and 8.3 before 8.3.12, and in the End-of-Life PHP 7.4 (from 7.4.4) and 8.0 release lines, which never received the upstream fix. The PHP project scores it 3.3 under CVSS 3.1 (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N).
With catch_workers_output = yes, each worker's stdout and stderr are pipes that the master reads in fpm_stdio_child_said(), splitting the data into log lines. A worker ends a message early by writing a flush marker, the six bytes of "\0fscf" including the terminating NUL. When a read ends partway through the marker, the master remembers in cmd_pos how many marker bytes it has seen and checks the rest at the start of the next read. In PHP 7.4.33 that code reads:
if (cmd_pos > 0) {
if ((sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos) <= in_buf &&
!memcmp(buf, &FPM_STDIO_CMD_FLUSH[cmd_pos], sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos)) {
zlog_stream_finish(log_stream);
start = cmd_pos;
} else {
zlog_stream_str(log_stream, &FPM_STDIO_CMD_FLUSH[0], cmd_pos);
}
cmd_pos = 0;
}After a matching split marker, parsing should resume after the remaining sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos bytes, but the code resumes after cmd_pos bytes. Depending on where the split falls, the master either skips real characters of the next message or copies leftover marker bytes into it. A script that controls what it writes to stderr, and so where the marker falls in the pipe data, can use this to cut up to 4 characters from the following log message or add characters to it; the CVE record notes that with syslog output more log data can be removed.
Exploitation needs php-fpm with catch_workers_output = yes, which is off by default, and a script that writes attacker-influenced data to stderr. The impact is limited to the integrity of the FPM log, which can help an attacker hide or confuse traces of other activity. The PHP CLI and other SAPIs do not contain the FPM code and are not affected.
The fix, by Jakub Zelenka, resumes parsing after the correct number of bytes:
zlog_stream_finish(log_stream);
start = sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos;Mitigation
The PHP project publishes security fixes only for its supported release lines. PHP 7.4 and 8.0 are End-of-Life and will not receive any public updates to address this issue.
Until an upgrade is possible, leave catch_workers_output at its default of no in PHP-FPM pools that run untrusted or attacker-influenced code, and do not rely on worker output in the FPM log for security auditing.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 8.1.30, 8.2.24, 8.3.12, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- Sébastien Rolland (finder)
- Jakub Zelenka (remediation)