CVE-2019-9640
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. Its EXIF extension reads the metadata and embedded thumbnails of JPEG and TIFF images, through functions such as exif_read_data() and exif_thumbnail().
An Out-of-Bounds Read vulnerability (CVE-2019-9640) has been identified in the thumbnail scanning code of PHP's EXIF extension, which allows an attacker who can supply an image to an application that reads its EXIF data or thumbnail to make PHP read past the end of the thumbnail data. PHP tracks this issue as bug #77540.
Per MITRE CWE-125: The product reads data past the end, or before the beginning, of the intended buffer.
This issue affects PHP before 7.1.27, PHP 7.2 before 7.2.16 and PHP 7.3 before 7.3.3, which includes the End-of-Life PHP 5.6 and 7.0 release lines through their final releases (5.6.40 and 7.0.33).
Details
Module Info
- Product: PHP
- Affected packages:
php-src(ext/exif) - Affected versions: <7.1.27, >=7.2.0 <7.2.16, >=7.3.0 <7.3.3
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 7.1.27, 7.2.16, 7.3.3
- NES for PHP 5.6.1 (based on PHP 5.6.40)
Vulnerability Info
This High-severity vulnerability is found in the EXIF extension of PHP before 7.1.27, 7.2 before 7.2.16 and 7.3 before 7.3.3, including the End-of-Life PHP 5.6 and 7.0 release lines, which never received the fix. The CVE record, published by MITRE, carries no CVSS score; NVD scores it 7.5 under CVSS 3.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N). The record describes it as an invalid read in exif_process_SOFn().
When an image carries an embedded JPEG thumbnail, exif_scan_thumbnail() walks the thumbnail's segments to find its width and height. For a start-of-frame (SOFn) segment it calls exif_process_SOFn(), which reads the bytes at offsets 2 through 7 of the segment. In PHP 5.6.40 the bounds check before that call reads:
length = php_jpg_get16(data+pos);
if (pos+length>=ImageInfo->Thumbnail.size) {
return FALSE;
}The segment length comes from the image itself. The check does not make sure that the segment is long enough for the bytes exif_process_SOFn() reads, and the addition pos+length could wrap. The reporter showed that a crafted thumbnail with a short SOFn segment at its end makes exif_thumbnail() read past the end of the thumbnail buffer. The values read become the reported thumbnail width and height, and an invalid read may also crash the process.
Exploitation needs an application that calls exif_read_data() or exif_thumbnail() on an image the attacker supplies. This applies to any SAPI where the EXIF extension is enabled. Applications that do not process EXIF data from untrusted images are not exposed.
The fix rewrites the segment length check so that it cannot overflow, and requires a SOFn segment to have the 8 bytes exif_process_SOFn() needs before calling it. In the PHP 5.6 port, a thumbnail that cannot be scanned reports a width and height of 0.
if (length < 8 || ImageInfo->Thumbnail.size - 8 < pos) {
/* exif_process_SOFn needs 8 bytes */
return FALSE;
}Mitigation
The PHP project publishes security fixes only for its supported release lines. PHP 5.6 and 7.0 are End-of-Life and will not receive any public updates to address this issue.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 7.1.27, 7.2.16, 7.3.3, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- chamal.desilva (finder)
- Stanislav Malyshev (remediation)