CVE-2019-11038
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 GD extension creates and manipulates images, and in most builds it uses a copy of the GD Graphics Library (libgd) bundled with PHP.
An Information Exposure vulnerability (CVE-2019-11038) has been identified in the gdImageCreateFromXbm() function of the libgd copy bundled with PHP's GD extension, which allows an attacker who can supply an XBM image to an application that loads it with imagecreatefromxbm() to have leftover stack memory written into the pixels of the resulting image. PHP tracks this issue as bug #77973.
Per MITRE CWE-457: The code uses a variable that has not been initialized, leading to unpredictable or unintended results.
This issue affects PHP before 7.1.30, PHP 7.2 before 7.2.19 and PHP 7.3 before 7.3.6, 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/gd) - Affected versions: <7.1.30, >=7.2.0 <7.2.19, >=7.3.0 <7.3.6
- 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.30, 7.2.19, 7.3.6
- NES for PHP 5.6.1 (based on PHP 5.6.40)
Vulnerability Info
This Low-severity vulnerability is found in the bundled libgd of PHP before 7.1.30, 7.2 before 7.2.19 and 7.3 before 7.3.6. The CVE record does not list PHP 5.6 or 7.0, but HeroDevs' analysis found the same code in the End-of-Life PHP 5.6 and 7.0 release lines, which never received the fix. The PHP project scores it 3.1 under CVSS 3.0 (CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N).
XBM is a plain-text image format: the pixel data is a C array of hexadecimal byte values such as 0x3c. gdImageCreateFromXbm(), which backs imagecreatefromxbm(), reads the characters after each x and converts them with sscanf() into the variable b, whose bits become pixels. In PHP 5.6.40 the code reads:
sscanf(h, "%x", &b);
for (bit = 1; bit <= max_bit; bit = bit << 1) {
gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0);The return value of sscanf() is not checked, and b is a local variable that is never initialized. When the characters after an x are not hexadecimal digits, sscanf() stores nothing and b keeps whatever value was left on the stack by earlier code. That value is then drawn into the image, so a crafted XBM file can produce an image whose pixels reflect stack contents.
Exploitation needs an application that loads an XBM image the attacker supplies and makes the resulting image, or data derived from it, visible to the attacker. Only builds that use the libgd bundled with PHP contain this code, under any SAPI. Because b is a single integer, the amount of memory exposed this way is small. Applications that do not process XBM images from untrusted sources are not exposed.
The fix checks that sscanf() actually read a hexadecimal value and otherwise rejects the image with an "invalid XBM" warning, so imagecreatefromxbm() returns false:
if (sscanf(h, "%x", &b) != 1) {
php_gd_error("invalid XBM");
gdImageDestroy(im);
return 0;
}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.
Until an upgrade is possible, do not pass XBM images from untrusted sources to imagecreatefromxbm().
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 7.1.30, 7.2.19, 7.3.6, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- chamal.desilva (finder)
- Christoph M. Becker (remediation)