CVE-2026-6103
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 archives and plain tar archives, through the Phar and PharData classes and the phar:// stream wrapper.
An Integer Overflow vulnerability (CVE-2026-6103) has been identified in the tar parser of PHP's phar extension, which allows an attacker who can supply a crafted tar or phar archive to make PHP see entries that other tools do not see, and hide entries that they do, so that content checked by one tool is not what PHP extracts. PHP tracks this issue as GHSA-j3wh-g957-2m85.
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 8.2 before 8.2.34, PHP 8.3 before 8.3.35, PHP 8.4 before 8.4.26 and PHP 8.5 before 8.5.11, as well as all releases of the End-of-Life PHP 5.6 through 8.1 release lines.
Details
Module Info
- Product: PHP
- Affected packages:
php-src(ext/phar) - Affected versions: <8.2.34, >=8.3.0 <8.3.35, >=8.4.0 <8.4.26, >=8.5.0 <8.5.11
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 8.2.34, 8.3.35, 8.4.26, 8.5.11
- NES for PHP 5.6.1 (based on PHP 5.6.40)
- NES for PHP 7.2.1 (based on PHP 7.2.34)
- NES for PHP 7.4.1 (based on PHP 7.4.33)
Vulnerability Info
This Medium-severity vulnerability is found in the phar extension of PHP 8.2 before 8.2.34, 8.3 before 8.3.35, 8.4 before 8.4.26 and 8.5 before 8.5.11, and in the End-of-Life PHP 5.6 through 8.1 release lines, which never received the upstream fix. The PHP project scores it 4.3 under CVSS 3.1 (CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N).
A tar archive is a sequence of 512-byte headers, each followed by the entry's data padded to a multiple of 512 bytes. phar_parse_tarfile() walks the archive by reading a header, taking the entry size from its 11-digit octal size field, and skipping that many data blocks to reach the next header. In PHP 7.4.33 the size is parsed by:
static uint32_t phar_tar_number(char *buf, size_t len) /* {{{ */
{
uint32_t num = 0;
size_t i = 0;
while (i < len && buf[i] == ' ') {
++i;
}
while (i < len && buf[i] >= '0' && buf[i] <= '7') {
num = num * 8 + (buf[i] - '0');
++i;
}
return num;
}
The size field can hold values up to 0x1FFFFFFFF, but the result is a 32-bit integer with no overflow check, so a larger size silently wraps around. The parser then skips the wrong number of blocks and reads attacker-controlled entry content as the next tar header. Separately, the parser only skipped the data of regular file entries, so the data of other entry types that carry data was also read as headers. Either way, a crafted archive can contain entries that PharData lists and extracts as if they were genuine while other tar implementations treat the same bytes as file content, and the reverse. The CVE record calls this archive entry injection.
Exploitation needs an application that opens a tar or phar archive an attacker supplies, with PharData, Phar or a phar:// path, typically after another tool such as an upload scanner or validation step has inspected it. An attacker can then get entries past that check that the checking tool never saw. Any SAPI is affected when the phar extension is loaded, which is the default. Applications that never open untrusted archives with the phar extension are not exposed.
The fix, by Jakub Zelenka, parses entry sizes strictly and refuses values that cannot be represented, skips the data blocks of every entry type that carries data, and refuses GNU long link records. The new size check reads:
while (i < len && buf[i] >= '0' && buf[i] <= '7') {
num = num * 8 + (buf[i] - '0');
++i;
}
while (i < len && (buf[i] == ' ' || buf[i] == '\0')) {
++i;
}
if (i != len || num > UINT32_MAX - 511) {
return false;
}
Mitigation
The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0 and 8.1 are End-of-Life and will not receive any public updates to address this issue.
Until an upgrade is possible, do not open untrusted tar or phar archives with the phar extension, or extract them with the same tool that validated them, and disable the phar extension where it is not needed.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 8.2.34, 8.3.35, 8.4.26, 8.5.11, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- arnoldasr (finder)
- Oblivionsage (finder)
- OSTIF-Derek (finder)
- Jakub Zelenka (remediation)