CVE-2019-11046

Buffer Over-read
Affects
PHP
in
PHP
No items found.
Versions
<7.2.26, >=7.3.0 <7.3.13, >=7.4.0 <7.4.1

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 BCMath extension provides arbitrary precision arithmetic on numbers passed as strings, through functions such as bcadd() and bcmul().

An Out-of-Bounds Read vulnerability (CVE-2019-11046) has been identified in the number parsing of PHP's BCMath extension, which allows an attacker who can supply a number string to BCMath functions on some systems, including Windows, to make the extension read memory outside the buffer that holds the number. PHP tracks this issue as bug #78878.

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.2.26, PHP 7.3 before 7.3.13 and PHP 7.4.0, which includes the End-of-Life PHP 5.6, 7.0 and 7.1 release lines through their final releases (5.6.40, 7.0.33 and 7.1.33).

Details

Module Info

Vulnerability Info

This Low-severity vulnerability is found in the BCMath extension of PHP before 7.2.26, 7.3 before 7.3.13 and 7.4.0. The CVE record does not list PHP 5.6, 7.0 or 7.1, but HeroDevs' analysis found the same code in the End-of-Life PHP 5.6, 7.0 and 7.1 release lines, which never received the fix. The PHP project scores it 3.7 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N).

Every BCMath function first converts its string arguments to an internal number with bc_str2num(). The function makes one pass to validate the string and count its digits, then a second pass that stores each digit as its numeric value. In PHP 5.6.40 the first pass classifies digits with the C library's isdigit():

while (*ptr == '0') ptr++; /* Skip leading zeros. */
while (isdigit((int)*ptr)) ptr++, digits++; /* digits */
if (*ptr == '.') ptr++; /* decimal point */
while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */

The rest of the library only handles the ASCII digits 0 to 9, and converts each one by subtracting the character '0'. On some systems, including Windows, isdigit() reports certain bytes above 0x7F as digits. Such a byte passes validation and is stored as a value that is not a decimal digit. The reporter showed that arithmetic on such a number made bc_shift_addsub() read before the start of its buffer and crash the process on Windows. The CVE record notes that this can disclose the contents of some memory locations.

Exploitation needs an application that passes strings the attacker controls to BCMath functions, on a platform whose C library treats bytes above 0x7F as digits. HeroDevs' analysis found that glibc's isdigit() rejects those bytes, so Linux builds that use glibc do not read out of bounds; the fix is still applied on every platform. Applications that validate numeric input before passing it to BCMath, or that do not use BCMath, are not exposed.

The fix stops relying on the C library and accepts only the ASCII characters 0 to 9 as digits:

while (*ptr >= '0' && *ptr <= '9') ptr++, digits++; /* digits */
if (*ptr == '.') ptr++; /* decimal point */
while (*ptr >= '0' && *ptr <= '9') ptr++, strscale++; /* digits */

Mitigation

The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0 and 7.1 are End-of-Life and will not receive any public updates to address this issue.

Until an upgrade is possible, validate that strings passed to BCMath functions contain only an optional sign, the ASCII digits 0 to 9 and at most one decimal point.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to PHP 7.2.26, 7.3.13, 7.4.1, 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
Low
ID
CVE-2019-11046
PROJECT Affected
PHP
Versions Affected
<7.2.26, >=7.3.0 <7.3.13, >=7.4.0 <7.4.1
NES Versions Affected
Published date
December 23, 2019
≈ Fix date
December 18, 2019
Fixed in
Category
Buffer Over-read
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.