CVE-2016-7480

Improper Input Validation (4.16)
Affects
PHP (php-src)
in
PHP
No items found.
Versions
<7.0.12

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 SPL extension provides SplObjectStorage, a container that maps objects to data and can be serialized and unserialized.

An Improper Input Validation vulnerability (CVE-2016-7480) has been identified in the SplObjectStorage::unserialize() method of PHP's SPL extension, which allows an attacker who can supply serialized data to an application that unserializes it to make the storage keep a value that is not an object as one of its keys. PHP tracks this issue as bug #73257, together with the closely related bug #73258.

Per MITRE CWE-20: The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.

This issue affects PHP before 7.0.12, which includes the End-of-Life PHP 5.6 release line through its final release, 5.6.40.

Details

Module Info

Vulnerability Info

This Critical-severity vulnerability is found in the SPL extension of PHP before 7.0.12, including the End-of-Life PHP 5.6 release line, which never received the upstream fix. The CVE record, published by Check Point, 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 record describes a missing check that a key is an object and an uninitialized memory access that could lead to code execution or a crash. HeroDevs' analysis found that the uninitialized variables belong to PHP 7 code; on PHP 5.6 the issue is the non-object key reported in bug #73258.

A serialized SplObjectStorage holds a list of entries, each an object followed by the information attached to it. SplObjectStorage::unserialize() reads them one at a time. In PHP 5.6.40 it unserializes the object, checks its type, and only then unserializes the information:

var_push_dtor(&var_hash, &pentry);
if(Z_TYPE_P(pentry) != IS_OBJECT) {
    zval_ptr_dtor(&pentry);
    goto outexcept;
}
ALLOC_INIT_ZVAL(pinf);
if (*p == ',') { /* new version has inf */
    ++p;
    if (!php_var_unserialize(&pinf, &p, s + buf_len, &var_hash TSRMLS_CC)) {
        zval_ptr_dtor(&pinf);
        goto outexcept;
    }
    var_push_dtor(&var_hash, &pinf);
}

The type check happens too early. The information that follows the key is attacker-controlled serialized data, and it can contain a reference back to the key. Through that reference, a __wakeup() method that runs while the information is unserialized can change the key after it passed the check. The storage then attaches an entry whose key is no longer an object. The reporter described this as a type confusion. Code that later relies on every key being an object may then work on a value of the wrong type.

Exploitation needs an application that passes attacker-controlled data to unserialize(), allows SplObjectStorage in that data, and has a class with a __wakeup() method available. This applies to any SAPI, and OPcache does not change it. Applications that never unserialize untrusted data are not exposed.

The upstream fix, in PHP 7.0.12, and its port to PHP 5.6 check the key only after its information has been unserialized, refuse a key that a reference points to, and make the storage keep its own copy of each key, so later changes through a reference cannot reach it.

Mitigation

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

Until an upgrade is possible, do not pass untrusted data to unserialize(); use a data format such as JSON for input that crosses a trust boundary.

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

  • Upgrade to PHP 7.0.12, 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-2016-7480
PROJECT Affected
PHP (php-src)
Versions Affected
<7.0.12
NES Versions Affected
Published date
January 11, 2017
≈ Fix date
October 13, 2016
Fixed in
Category
Improper Input Validation (4.16)
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.