CVE-2020-7068
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 phar extension reads and writes PHP Archive (Phar) files, including zip-based ones, and exposes them through the phar:// stream wrapper.
A Use After Free vulnerability (CVE-2020-7068) has been identified in the zip archive parser of PHP's phar extension, which allows an attacker who can supply a crafted zip-based Phar archive to make PHP read memory that has already been freed, which can crash the process or disclose memory contents. PHP tracks this issue as bug #79797.
Per MITRE CWE-416: The product reuses or references memory after it has been freed.
This issue affects all versions of PHP before 7.2.33, PHP 7.3 before 7.3.21 and PHP 7.4 before 7.4.9, which includes the End-of-Life release lines PHP 5.6, 7.0 and 7.1 through their final releases (5.6.40, 7.0.33 and 7.1.33).
Details
Module Info
- Product: PHP
- Affected packages:
php-src(ext/phar) - Affected versions: <7.2.33, >=7.3.0 <7.3.21, >=7.4.0 <7.4.9
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 7.2.33, 7.3.21, 7.4.9
- NES for PHP 5.6.1 (based on PHP 5.6.40)
Vulnerability Info
This Medium-severity vulnerability is found in the phar extension of all versions of PHP before 7.2.33, PHP 7.3 before 7.3.21 and PHP 7.4 before 7.4.9, including the End-of-Life PHP 5.6, 7.0 and 7.1 release lines, which never received the upstream fix. The PHP project scores it 4.8 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:L).
A Phar archive can declare an alias, a short name under which PHP registers it in an internal alias map. When phar_parse_zipfile() opens a zip-based archive that carries an alias, it copies the alias read from the archive into the archive's own record and then adds it to the map. In PHP 5.6.40, the code reads:
mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias;
if (entry.is_persistent) {
efree(actual_alias);
}
zend_hash_add(&(PHAR_GLOBALS->phar_alias_map), actual_alias, mydata->alias_len, (void*)&mydata, sizeof(phar_archive_data*), NULL);When the archive is persistent, the alias is first duplicated into persistent memory and the original buffer actual_alias is freed, but the freed buffer, not the persistent copy, is then used as the key for the alias map. PHP therefore reads freed heap memory, which may by then hold other data such as allocator metadata, into the map. The reporter showed heap addresses ending up in the map key. The CVE record states that this can lead to a crash or information disclosure.
The freeing path is taken only for persistent archives. The reporter notes that entry.is_persistent is set when the archive is listed in the phar.cache_list ini setting, so the issue is reachable when such an archive, crafted or modified by an attacker, carries an alias. Any SAPI can reach this path when an application opens such an archive, including through the phar:// wrapper. Applications that do not use the phar extension are not affected.
The fix registers the alias using the archive's own copy, which remains valid:
mydata->alias = entry.is_persistent ? pestrndup(actual_alias, mydata->alias_len, 1) : actual_alias;
if (entry.is_persistent) {
efree(actual_alias);
}
zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata);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, list in phar.cache_list only archives that untrusted parties cannot create or modify, and do not open zip-based Phar archives from untrusted sources.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 7.2.33, 7.3.21, 7.4.9, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- grigoritchy (finder)
- Christoph M. Becker (remediation)