CVE-2019-9641

Integer Overflow or Wraparound
Affects
PHP (php-src)
in
PHP
No items found.
Versions
<7.1.27, >=7.2.0 <7.2.16, >=7.3.0 <7.3.3

Patch Available.

Exclamation circle icon
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 that cameras embed in JPEG and TIFF images, through functions such as exif_read_data().

An Integer Overflow vulnerability (CVE-2019-9641) has been identified in exif_process_IFD_in_TIFF(), part of PHP's EXIF extension, which allows an attacker who supplies a crafted TIFF image to a 32-bit PHP build to bypass its bounds checks, so that PHP parses uninitialized memory and data outside the file as EXIF directory entries. PHP tracks this issue as bug #77509.

Per MITRE CWE-190: The product performs a calculation that can produce an integer overflow or wraparound when the logic assumes that the resulting value will always be larger than the original value. This occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may become a very small or negative number.

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 release line through its final release (5.6.40). Only 32-bit builds can reach the flaw.

Details

Module Info

Vulnerability Info

This Critical-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. The CVE record, assigned by MITRE, gives no CVSS score; NVD scores it 9.8 under CVSS 3.1 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). The End-of-Life PHP 5.6 release line never received the upstream fix.

A TIFF file stores its metadata in image file directories (IFDs), each found at an offset given in the file. Before reading a directory, exif_process_IFD_in_TIFF() checks that the offset and the directory size fit inside the file. In PHP 5.6.40 the first check reads:

if (ImageInfo->FileSize >= dir_offset+2) {
    sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL);
#ifdef EXIF_DEBUG
    exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read from TIFF: filesize(x%04X), IFD dir(x%04X + x%04X)", ImageInfo->FileSize, dir_offset, 2);
#endif
    php_stream_seek(ImageInfo->infile, dir_offset, SEEK_SET); /* we do not know the order of sections */
    php_stream_read(ImageInfo->infile, (char*)ImageInfo->file.list[sn].data, 2);
    num_entries = php_ifd_get16u(ImageInfo->file.list[sn].data, ImageInfo->motorola_intel);

The offset comes from the file and is added to a size before the comparison. On a 32-bit build, where size_t is 32 bits wide, an offset close to 4 GiB wraps around when 2 is added, so the check passes. The seek and read then fail because the offset lies past the end of the file, and the parser goes on to decode the uninitialized buffer as a directory entry count. The later checks in the same function, which add the directory size and the IFD size to the offset, can wrap the same way. The reporter showed the effect with an 8-byte file under Valgrind.

Exploitation needs a 32-bit PHP build and an application that reads EXIF data, for example with exif_read_data(), from a TIFF image an attacker supplies. On 64-bit builds the offsets cannot wrap. HeroDevs' analysis notes that NES for PHP 5 ships x86_64 builds only, so its packages were not exposed; the fix is carried so the code matches upstream.

The fix rewrites each check to subtract from the file size instead of adding to the offset, so no sum can wrap:

if (ImageInfo->FileSize >= 2 && ImageInfo->FileSize - 2 >= dir_offset) {

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

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Critical
ID
CVE-2019-9641
PROJECT Affected
PHP (php-src)
Versions Affected
<7.1.27, >=7.2.0 <7.2.16, >=7.3.0 <7.3.3
NES Versions Affected
Published date
March 8, 2019
≈ Fix date
March 7, 2019
Fixed in
Category
Integer Overflow or Wraparound
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
PHP
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.