CVE-2024-8925
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. Before a script runs, PHP parses multipart/form-data POST bodies, such as HTML form submissions and file uploads, into $_POST and $_FILES.
An Improper Input Validation vulnerability (CVE-2024-8925) has been identified in PHP's multipart form data parser, which allows an attacker who can control part of a submitted request to choose a boundary longer than the parser's read buffer, so that parts of the body are merged into another field or dropped and other form data is hidden from the application. PHP tracks this issue as GHSA-9pqp-7h25-4f32.
Per MITRE CWE-20: The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.
This issue affects PHP before 8.1.30, PHP 8.2 before 8.2.24 and PHP 8.3 before 8.3.12, which includes the End-of-Life release lines PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 through their final releases.
Details
Module Info
- Product: PHP
- Affected packages:
php-src(main/rfc1867.c) - Affected versions: <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 5.6.1 (based on PHP 5.6.40)
- NES for PHP 7.2.1 (based on PHP 7.2.34)
- NES for PHP 7.4.1 (based on PHP 7.4.33)
Vulnerability Info
This Low-severity vulnerability is found in the multipart form data parser of PHP before 8.1.30, 8.2 before 8.2.24 and 8.3 before 8.3.12, including the End-of-Life PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 release lines, which never received the upstream fix. The PHP project scores it 3.1 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N), and CISA-ADP classifies it as CWE-444, Inconsistent Interpretation of HTTP Requests.
A multipart/form-data body is split into parts by a boundary string that the client chooses and declares in the Content-Type header. PHP's parser in main/rfc1867.c reads the body through a buffer of FILLUNIT bytes (5 KiB) and looks for the boundary in the data it has buffered. Before the fix, the request handler accepted a boundary of any length and went straight on to set up the buffer:
if (boundary_end) {
boundary_end[0] = '\0';
boundary_len = boundary_end-boundary;
}
/* Initialize the buffer */
if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
return;
}When the boundary is longer than the read buffer allows, a boundary that is split across two reads is not recognized. Part of the body can then be appended to the previous field or skipped, so the fields PHP builds differ from what the client sent. The CVE record describes the result as legitimate data not being processed, so an attacker who controls part of the submitted data may be able to exclude other parts of it, which can lead to erroneous application behavior. HeroDevs' analysis confirms the same behavior on PHP 5.6, 7.2 and 7.4.
The body is parsed before the script runs, so any script that receives multipart POST requests is affected, under the server APIs that parse POST bodies: php-fpm, CGI, the Apache module and the CLI built-in server. Exploitation needs an attacker who can control part of the submitted data, which the CVSS vector reflects with high attack complexity and low privileges required. There is no memory corruption or information disclosure.
The fix rejects boundaries longer than the parser can handle, with a warning, before it allocates the buffer. RFC 1521 limits boundaries to 70 characters, and PHP keeps accepting anything it could already parse correctly:
/* Boundaries larger than FILLUNIT-strlen("\r\n--") characters lead to
* erroneous parsing */
if (boundary_len > FILLUNIT-strlen("\r\n--")) {
sapi_module.sapi_error(E_WARNING, "Boundary too large in multipart/form-data POST data");
return;
}Mitigation
The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0, 7.1, 7.2, 7.3, 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, a web server or proxy in front of PHP can reject multipart/form-data requests whose boundary is longer than the 70 characters RFC 1521 allows.
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
- Mihail Kirov (finder)
- Arnaud Le Blanc (remediation)