CVE-2017-9120

Integer Overflow or Wraparound
Affects
PHP (php-src)
in
PHP
No items found.
Versions
>=7.0.0 <7.4.23, >=8.0.0 <8.0.10

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 mysqli extension connects PHP applications to MySQL and MariaDB servers.

An Integer Overflow vulnerability (CVE-2017-9120) has been identified in the mysqli_real_escape_string() function of PHP's mysqli extension, which allows an attacker who can supply a very long string to an application that escapes it with this function to make PHP write past the end of a heap buffer on 32-bit builds, which can crash the process and may have other impact. PHP tracks this issue as bug #74544.

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 issue affects PHP 7 before 7.4.23 and PHP 8.0 before 8.0.10, which includes the End-of-Life release lines PHP 7.0, 7.1, 7.2 and 7.3 through their final releases (7.0.33, 7.1.33, 7.2.34 and 7.3.33).

Details

Module Info

Vulnerability Info

This Critical-severity vulnerability is found in the mysqli extension of PHP 7 before 7.4.23 and PHP 8.0 before 8.0.10, including the End-of-Life PHP 7.0, 7.1, 7.2 and 7.3 release lines, which never received the upstream fix. The CVE record, assigned by MITRE, describes PHP 7.x through 7.1.5 (the version the reporter tested) and carries 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 upstream bug stayed open until 2021, and the unchecked code is still present in PHP 7.2.34 and 8.0.9.

mysqli_real_escape_string() (and mysqli::real_escape_string()) escapes special characters in a string so an application can place it in an SQL statement. Because escaping can at most double the length of the input, PHP allocates an output buffer of twice the input length and lets the MySQL client library fill it. In PHP 7.2.34, the function reads:

MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);

newstr = zend_string_alloc(2 * escapestr_len, 0);
ZSTR_LEN(newstr) = mysql_real_escape_string(mysql->mysql, ZSTR_VAL(newstr), escapestr, escapestr_len);
newstr = zend_string_truncate(newstr, ZSTR_LEN(newstr), 0);

RETURN_NEW_STR(newstr);

The multiplication 2 * escapestr_len is not checked. On a 32-bit build, where size_t holds 32 bits, a string of more than 2 GiB makes the product wrap to a small number, so PHP allocates a tiny buffer and the escaping routine then writes the full escaped string past its end. The reporter showed a 2 GiB input producing an allocation of 8 bytes. A heap overflow of this kind crashes PHP and may have other, unspecified impact, as the CVE record states.

Exploitation needs an application that passes attacker-controlled input of more than 2 GiB to mysqli_real_escape_string(), and a memory_limit (and, for request data, post_max_size) large enough to hold it. HeroDevs' analysis limits the issue to 32-bit builds: on 64-bit builds the multiplication cannot wrap for any string PHP can hold, so 64-bit servers are not exposed. Applications that use prepared statements with bound parameters instead of escaping strings do not call the function at all.

The fix allocates the buffer with zend_string_safe_alloc(), which checks the multiplication and stops with a fatal error instead of allocating a short buffer:

newstr = zend_string_safe_alloc(2, escapestr_len, 0, 0);

Mitigation

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

Until an upgrade is possible, run PHP as a 64-bit build, use prepared statements with bound parameters instead of mysqli_real_escape_string(), and keep memory_limit and post_max_size well below the sizes needed to reach the overflow.

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

  • Upgrade to PHP 7.4.23, 8.0.10, 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-2017-9120
PROJECT Affected
PHP (php-src)
Versions Affected
>=7.0.0 <7.4.23, >=8.0.0 <8.0.10
NES Versions Affected
Published date
August 2, 2018
≈ Fix date
August 19, 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.