CVE-2026-59933
PHP vulnerability analysis and mitigation

Overview

CVE-2026-59933 is a denial-of-service vulnerability in PHPOffice/PhpSpreadsheet caused by an infinite sector-chain loop in the OLE reader, allowing a tiny malformed XLS file to exhaust PHP process memory. It affects all major supported branches: versions ≤ 1.30.5, 2.0.0–2.1.17, 2.2.0–2.4.6, 3.3.0–3.10.6, and 4.0.0–5.8.0. The vulnerability was published to the GitHub Advisory Database on July 23, 2026, with patched versions released on July 12, 2026. It carries a CVSS v3.1 base score of 7.5 (High) (GitHub Advisory).

Technical details

The root cause is classified as CWE-400 (Uncontrolled Resource Consumption) and CWE-835 (Loop with Unreachable Exit Condition). In OLERead::read() (src/PhpSpreadsheet/Shared/OLERead.php), the small-block depot sector chain is traversed in a while ($sbdBlock != -2) loop that appends sector data to $this->smallBlockChain on each iteration. Because there is no visited-sector set, no maximum iteration count, and no bounds check, a crafted OLE file that sets the sector allocation table (SAT) entry for sector 0 to point back to sector 0 causes the loop to run indefinitely, appending the same data until the PHP process exhausts its memory limit. This code path is reachable from Reader\Xls::canRead() and IOFactory's automatic format detection, meaning exploitation requires only that the application pass an attacker-supplied file to the reader — no authentication or user interaction is needed. A public proof-of-concept (a ~1 KiB crafted OLE file) is included in the advisory (GitHub Advisory, Patch Commit).

Impact

Successful exploitation causes a fatal PHP memory exhaustion error, crashing the PHP worker process handling the upload. This affects availability of web applications, queue workers, document preview services, and file converters that process untrusted spreadsheet uploads. There is no confidentiality or integrity impact; the vulnerability is purely a denial-of-service issue. Because the crash occurs during file-type detection — before any workbook content is parsed — even lightweight probing or detection code paths are vulnerable (GitHub Advisory).

Exploitation steps

  1. Craft the malicious file: Generate a ~1 KiB OLE/XLS file with a valid OLE magic header (D0CF11E0A1B11AE1) but with the SAT entry for sector 0 set to point back to sector 0 (self-loop), as demonstrated in the advisory PoC.
  2. Identify a target endpoint: Locate a web application, API, or service that accepts .xls spreadsheet uploads and uses PhpSpreadsheet for processing or format detection (versions ≤ 1.30.5, 2.0.0–2.1.17, 2.2.0–2.4.6, 3.3.0–3.10.6, or 4.0.0–5.8.0).
  3. Upload the malformed file: Submit the crafted file to the target's file upload endpoint via a standard HTTP POST request — no authentication is required if the endpoint is public.
  4. Trigger memory exhaustion: When the application calls IOFactory::load(), Xls::canRead(), or any automatic format detection, OLERead::read() enters the infinite sector-chain loop and exhausts the PHP process memory, resulting in a fatal error and worker crash.
  5. Repeat for sustained DoS: Repeatedly submitting the file (or submitting multiple files concurrently) can exhaust all available PHP worker processes, rendering the application unavailable (GitHub Advisory).

Indicators of compromise

  • Logs: PHP error logs containing Fatal error: Allowed memory size of X bytes exhausted with a stack trace referencing OLERead.php line ~143 and XlsBase.php::canRead(); repeated occurrences in a short time window suggest active exploitation.
  • Logs: Web server access logs showing repeated POST requests to file upload endpoints with small file sizes (~1 KiB) and .xls extensions from the same or rotating source IPs.
  • File System: Presence of small (~1 KiB) .xls files in upload directories that contain the OLE magic bytes (D0CF11E0A1B11AE1) but are otherwise mostly null-padded.
  • Process: PHP-FPM or Apache mod_php worker processes terminating unexpectedly with out-of-memory errors, particularly correlated with file upload activity (GitHub Advisory).

Mitigation and workarounds

Upgrade PhpSpreadsheet to one of the patched versions: 1.30.6, 2.1.18, 2.4.7, 3.10.7, or 5.8.1, released on July 12, 2026. The fix introduces a catchLoop() helper that maintains a visited-sector set ($possibleLoop) and throws a recoverable ReaderException ("Detected loop while iterating blocks") instead of exhausting memory; this guard is applied to all sector-chain walks in OLERead.php. As a short-term workaround where upgrading is not immediately possible, restrict or disable untrusted .xls file uploads, enforce strict file-type validation before passing files to PhpSpreadsheet, and set a low PHP memory_limit combined with process-level memory controls to limit blast radius (GitHub Advisory, Patch Commit).

Additional resources


SourceThis report was generated using AI

Related PHP vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-47743HIGH8.7
  • PHP logoPHP
  • shopper/framework
NoYesJul 23, 2026
CVE-2026-59931HIGH7.7
  • PHP logoPHP
  • phpoffice/phpspreadsheet
NoYesJul 23, 2026
CVE-2026-59933HIGH7.5
  • PHP logoPHP
  • phpoffice/phpspreadsheet
NoYesJul 23, 2026
CVE-2026-59932HIGH7.5
  • PHP logoPHP
  • phpoffice/phpspreadsheet
NoYesJul 23, 2026
CVE-2026-59943MEDIUM6.3
  • PHP logoPHP
  • dompdf/dompdf
NoYesJul 22, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management