GHSA-xh5m-36r6-47m3: PHPSpreadsheet: XLS/OLE sector-chain self-loop causes memory exhaustion
Summary
PhpSpreadsheet's OLE reader follows sector chains from attacker-controlled XLS/OLE metadata without detecting cycles or enforcing a maximum chain length. A tiny malformed .xls/OLE file can set the small-block depot sector chain to point back to itself. During normal XLS detection, OLERead::read() appends the same sector data repeatedly until the PHP process exhausts memory.
This is reachable from Reader\Xls::canRead() and therefore from automatic spreadsheet type detection. Applications that accept attacker-controlled spreadsheet uploads can suffer denial of service from a very small file.
Vulnerability details
OLERead::read() loads the input and builds sector chains from attacker-controlled OLE header and allocation-table values:
- src/PhpSpreadsheet/Shared/OLERead.php:82 reads the entire file after validating only the OLE magic.
- src/PhpSpreadsheet/Shared/OLERead.php:84-97 reads sector-chain metadata from the file header.
- src/PhpSpreadsheet/Shared/OLERead.php:132-146 builds bigBlockChain and then follows the small-block depot chain.
The vulnerable loop is:
$sbdBlock = $this->sbdStartBlock;
$this->smallBlockChain = '';
while ($sbdBlock != -2) {
$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;
$this->smallBlockChain .= substr($this->data, $pos, 4 * $bbs);
$pos += 4 * $bbs;
$sbdBlock = self::getInt4d($this->bigBlockChain, $sbdBlock * 4);
}
There is no visited-sector set, no maximum iteration count, no EOF bound, and no check that the next sector differs from a previously visited sector. If the allocation table maps sector 0 to sector 0, the loop appends the same sector data forever until memory is exhausted.
The issue is reachable during normal reader detection/loading:
- src/PhpSpreadsheet/Reader/XlsBase.php:153-165 calls OLERead::read() from canRead().
- src/PhpSpreadsheet/Reader/Xls.php:376-383 calls OLERead::read() from loadOLE().
- src/PhpSpreadsheet/IOFactory.php:181-213 calls canRead() while creating a reader for a file, so automatic forma
Details
Original advisory: https://github.com/advisories/GHSA-xh5m-36r6-47m3
Exploitation outlook
EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.
- Low exploitation riskCVE-2026-599330.69% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 49% of all scored CVEs.
Referenced CVEs
| CVE | CSIRTS overview | External |
|---|---|---|
| CVE-2026-59933 | coverage & exploitation status | NVD · CVE.org |
Same CVEs, other sources
How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31