Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-j3wh-g957-2m85

Опубликовано: 24 сент. 2026
Источник: github
Github: Не прошло ревью
CVSS3: 4

Описание

Phar TAR phar_tar_number() Integer Overflow - Archive Entry Injection

Summary

phar_tar_number() parses the octal size field of a TAR header into a uint32_t with no overflow check. The field is 11 octal digits wide and holds values up to 0x1FFFFFFFF, so a size above 0xFFFFFFFF silently wraps. The parser then skips the wrong number of data blocks and interprets attacker-controlled file content as the next TAR header, which lets a crafted archive inject entries that PharData reports and extracts as if they were genuine.

Details

The parser accumulates octal digits without bounding the result:

https://github.com/php/php-src/blob/php-8.5.10/ext/phar/tar.c#L23-L38

Octal fieldTrue valueuint32_t resultEffect
377777777770xFFFFFFFF4294967295largest value that does not wrap
400000000000x1000000000size wraps to 0
400000000010x1000000011size wraps to 1
400000010000x100000200512size wraps to 512

When the size wraps to 0 the parser reads the size at line 275, rounds it up to a block boundary at line 585 where (0 + 511) & ~511 stays 0, then skips the data because the size > 0 condition at line 587 is false. The next 512 bytes read are the entry's own data, parsed as a TAR header.

The GNU long filename path has an overflow check, but it only rejects UINT_MAX and 0:

https://github.com/php/php-src/blob/php-8.5.10/ext/phar/tar.c#L368

A size that wraps to 1 passes it and allocates a one-byte buffer for what the header declares as a filename of more than 4 GB.

GNU tar rejects the same archive with not stopped at a record boundary, while PharData accepts it and exposes the injected entries.

The fix replaces the size parse with phar_tar_size(), which accumulates into a uint64_t, rejects the GNU base-256 encoding, requires the whole field to be consumed, and refuses any value above UINT32_MAX - 511. It also introduces phar_tar_type_has_data() so the data blocks of every entry type that carries data are skipped, and rejects the unsupported GNU long link record outright.

PoC

  1. Build a TAR archive with a legitimate entry followed by an entry whose size field is 40000000000.
  2. Place a valid TAR header in the data block immediately after that entry.
  3. Open the archive with new PharData($file).

The injected header is parsed as a real entry with an attacker-chosen name, size and content, and appears in the manifest alongside the legitimate entries. Reading through phar:// and extracting with extractTo() both return the injected version. Giving the injected entry the same name as a legitimate one replaces the original in the manifest, and a single overflow entry can introduce any number of further entries.

The regression tests ext/phar/tests/tar/GHSA-j3wh-g957-2m85-size.phpt, -longlink.phpt and -typeflag.phpt cover the wrapped size, the long filename check and the entry types that carry data.

Impact

An application that opens an untrusted TAR archive with PharData or the phar:// stream wrapper sees a set of entries that differs from what the archive actually contains, and extractTo() writes the injected entries to disk. Tooling that validates an archive before extracting it can be made to inspect one set of files and extract another.

Composer's TarDownloader uses new PharData($file) followed by extractTo() for every .tar.gz package, so a crafted package can place files into vendor/ that are not present in the archive as any other tool reads it.

Пакеты

Наименование

php

php
Затронутые версииВерсия исправления

>=8.2.0, <8.2.34

8.2.34

Наименование

php

php
Затронутые версииВерсия исправления

>=8.3.0, <8.3.35

8.3.35

Наименование

php

php
Затронутые версииВерсия исправления

>=8.4.0, <8.4.26

8.4.26

Наименование

php

php
Затронутые версииВерсия исправления

>=8.5.0, <8.5.11

8.5.11

EPSS

Процентиль: 5%
0.00167
Низкий

4 Medium

CVSS3

Связанные уязвимости

CVSS3: 4.3
ubuntu
19 дней назад

phar_tar_number() parses the octal size field of a TAR header into a uint32_t with no overflow check. The field is 11 octal digits wide and holds values up to 0x1FFFFFFFF, so a size above 0xFFFFFFFF silently wraps. The parser then skips the wrong number of data blocks and interprets attacker-controlled file content as the next TAR header, which lets a crafted archive inject entries that PharData reports and extracts as if they were genuine.

CVSS3: 4.3
redhat
19 дней назад

phar_tar_number() parses the octal size field of a TAR header into a uint32_t with no overflow check. The field is 11 octal digits wide and holds values up to 0x1FFFFFFFF, so a size above 0xFFFFFFFF silently wraps. The parser then skips the wrong number of data blocks and interprets attacker-controlled file content as the next TAR header, which lets a crafted archive inject entries that PharData reports and extracts as if they were genuine.

CVSS3: 4.3
nvd
19 дней назад

phar_tar_number() parses the octal size field of a TAR header into a uint32_t with no overflow check. The field is 11 octal digits wide and holds values up to 0x1FFFFFFFF, so a size above 0xFFFFFFFF silently wraps. The parser then skips the wrong number of data blocks and interprets attacker-controlled file content as the next TAR header, which lets a crafted archive inject entries that PharData reports and extracts as if they were genuine.

CVSS3: 4
msrc
15 дней назад

Phar TAR phar_tar_number() Integer Overflow - Archive Entry Injection

CVSS3: 4.3
debian
19 дней назад

phar_tar_number() parses the octal size field of a TAR header into a u ...

EPSS

Процентиль: 5%
0.00167
Низкий

4 Medium

CVSS3