CVE-2026-40863 Overview
CVE-2026-40863 is a denial-of-service vulnerability in PhpSpreadsheet, a pure PHP library for reading and writing spreadsheet files. The flaw resides in the SpreadsheetML XML reader (Reader\Xml), which fails to validate the ss:Index row attribute against the maximum allowed row count (AddressRange::MAX_ROW = 1,048,576). An attacker can submit a crafted SpreadsheetML XML document that inflates the internal cachedHighestRow value to roughly one billion rows. Any subsequent call to getRowIterator() without an explicit end row will iterate that range, exhausting CPU resources. The issue affects all releases prior to 1.30.4, 2.1.16, 2.4.5, 3.10.5, and 5.7.0. It is categorized under [CWE-770] Allocation of Resources Without Limits or Throttling.
Critical Impact
A single malicious SpreadsheetML upload can trigger near-billion-row iteration in PhpSpreadsheet, causing sustained CPU exhaustion and full denial of service on the host application.
Affected Products
- PHPOffice PhpSpreadsheet versions prior to 1.30.4
- PHPOffice PhpSpreadsheet versions 2.0.0 through versions prior to 2.1.16 and 2.4.5
- PHPOffice PhpSpreadsheet versions 3.x prior to 3.10.5 and 5.x prior to 5.7.0
Discovery Timeline
- 2026-05-12 - CVE-2026-40863 published to NVD
- 2026-05-13 - Last updated in NVD database
Technical Details for CVE-2026-40863
Vulnerability Analysis
The vulnerability is an unchecked resource allocation flaw in the SpreadsheetML XML reader. PhpSpreadsheet defines AddressRange::MAX_ROW as 1,048,576, matching the upper row limit of the OOXML specification. However, the Reader\Xml parser accepts the ss:Index attribute on a <Row> element without bounding it against this constant.
When the parser encounters an inflated index such as ss:Index="999999999", it updates the worksheet's cachedHighestRow to that attacker-controlled value. The cached value is later consumed by getRowIterator() when no explicit end row is supplied. The iterator then walks nearly one billion empty rows, saturating the CPU.
Root Cause
The root cause is missing input validation in the SpreadsheetML XML reader. The reader trusts attacker-controlled row indices and writes them directly into worksheet metadata. No clamp or sanity check enforces the documented AddressRange::MAX_ROW ceiling before the value influences iteration behavior.
Attack Vector
Exploitation requires no authentication or user interaction. Any application that accepts SpreadsheetML XML uploads and parses them with Reader\Xml, then calls getRowIterator() without specifying an end row, is exposed. An attacker submits a small XML file containing a <Row> element with ss:Index="999999999". Subsequent iteration consumes a worker process indefinitely, and repeated submissions can take down the entire application tier.
The vulnerability is described in the PHPOffice GitHub Security Advisory GHSA-84wq-86v6-x5j6.
Detection Methods for CVE-2026-40863
Indicators of Compromise
- SpreadsheetML XML files containing <Row> elements with ss:Index values greater than 1048576.
- PHP-FPM or web worker processes pinned at 100% CPU for extended periods after a spreadsheet upload.
- Application logs showing long-running calls into PhpOffice\PhpSpreadsheet\Reader\Xml::load() or Worksheet::getRowIterator().
Detection Strategies
- Inspect uploaded SpreadsheetML payloads at the application gateway and reject files where any ss:Index attribute exceeds the OOXML maximum row count.
- Instrument PhpSpreadsheet entry points with execution-time and memory metrics, and alert on parser invocations exceeding a defined threshold.
- Audit deployed phpoffice/phpspreadsheet versions in Composer lock files against the fixed releases.
Monitoring Recommendations
- Track CPU utilization on web and queue workers that process user-supplied spreadsheets and alert on sustained saturation.
- Log and review request paths that invoke spreadsheet ingestion endpoints, correlating elevated latency with specific uploads.
- Enable web application firewall (WAF) inspection rules that flag XML payloads containing oversized numeric attribute values.
How to Mitigate CVE-2026-40863
Immediate Actions Required
- Upgrade phpoffice/phpspreadsheet to 1.30.4, 2.1.16, 2.4.5, 3.10.5, or 5.7.0 depending on the major version in use.
- Until patched, disable SpreadsheetML XML ingestion paths or restrict spreadsheet uploads to authenticated, trusted users.
- Audit application code for calls to getRowIterator() that omit an explicit end row parameter and add bounded ranges.
Patch Information
PHPOffice fixed CVE-2026-40863 in PhpSpreadsheet releases 1.30.4, 2.1.16, 2.4.5, 3.10.5, and 5.7.0. The patched reader validates the ss:Index attribute against AddressRange::MAX_ROW before updating cachedHighestRow. Upgrade details are published in the PHPOffice security advisory GHSA-84wq-86v6-x5j6.
Workarounds
- Pre-validate SpreadsheetML XML uploads and reject documents whose ss:Index values exceed 1048576.
- Always pass an explicit end row to getRowIterator($startRow, $endRow) to bound iteration regardless of cached worksheet metadata.
- Enforce per-request CPU and execution time limits on PHP workers that handle spreadsheet parsing.
# Configuration example: upgrade PhpSpreadsheet via Composer to a fixed release
composer require phpoffice/phpspreadsheet:^5.7.0
# Or, for projects pinned to earlier major versions:
composer require phpoffice/phpspreadsheet:^3.10.5
composer require phpoffice/phpspreadsheet:^2.4.5
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


