CVE-2026-59932
PHP vulnerability analysis and mitigation

Overview

CVE-2026-59932 is a denial-of-service vulnerability in PHPOffice/PhpSpreadsheet's Gnumeric reader caused by unbounded gzip decompression, leading to memory exhaustion. When a .gnumeric file begins with gzip magic bytes, the library calls gzdecode() on the full compressed contents without enforcing a decompressed-size limit, allowing a tiny compressed file to exhaust PHP's memory limit and crash the process. The vulnerability affects 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. It was published on July 19, 2026, and carries a CVSS v3.1 base score of 7.5 (High) (GitHub Advisory).

Technical details

The root cause is improper handling of highly compressed data (CWE-409) combined with uncontrolled resource consumption (CWE-400). The vulnerable code path is in gzfileGetContents() (Gnumeric.php:192–197), which reads the entire input file into memory with file_get_contents(), detects gzip magic bytes (\x1f\x8b), and then calls gzdecode($contents) without a maximum output-size argument. This decompression occurs before any XML validation or structural checks, meaning even an invalid or malformed Gnumeric file triggers full memory allocation. The flaw is reachable through canRead(), listWorksheetNames(), listWorksheetInfo(), and load() — all standard file-type detection and import paths — so any application accepting attacker-supplied spreadsheet uploads is exposed. A public proof-of-concept is included in the advisory: a ~97 KB gzip payload expands to ~96 MiB and triggers a PHP fatal memory error under a 64 MB memory limit (GitHub Advisory, Patch Commit).

Impact

Successful exploitation causes a PHP fatal memory exhaustion error, crashing the PHP worker process handling the upload. This results in a denial-of-service condition affecting web applications, queue workers, document preview services, and any pipeline that processes untrusted spreadsheet files with PhpSpreadsheet. There is no confidentiality or integrity impact — the vulnerability is purely an availability issue — but repeated exploitation can render an entire file-processing service unavailable (GitHub Advisory).

Exploitation steps

  1. Craft the payload: Generate a gzip bomb targeting the .gnumeric extension. Using PHP: $payload = str_repeat("A", 96 * 1024 * 1024); $gz = gzencode($payload, 9); file_put_contents("bomb.gnumeric", $gz); — this produces a ~97 KB file that decompresses to ~96 MiB.
  2. Identify the target: Find a web application or API endpoint that accepts spreadsheet file uploads and processes them with PHPOffice/PhpSpreadsheet (versions ≤ 5.8.0).
  3. Upload the payload: Submit bomb.gnumeric as a file upload to the target endpoint. No special headers or authentication are required.
  4. Trigger decompression: PhpSpreadsheet's file-type detection calls Gnumeric::canRead(), which invokes gzfileGetContents(). The function detects gzip magic bytes and calls gzdecode() without a size cap, exhausting PHP memory.
  5. Achieve denial of service: The PHP worker crashes with a fatal memory error at Gnumeric.php:195, taking down the request handler. Repeated uploads can sustain the DoS condition against the service (GitHub Advisory).

Indicators of compromise

  • Logs: PHP error logs containing PHP Fatal error: Allowed memory size of ... bytes exhausted with a stack trace referencing PhpSpreadsheet/Reader/Gnumeric.php at or near line 195 and gzdecode().
  • Logs: Web server access logs showing repeated POST requests to file upload endpoints, particularly with .gnumeric file extensions or multipart/form-data content types, followed by 500-series HTTP responses.
  • File System: Presence of small (< 200 KB) .gnumeric files in upload directories that, when inspected, begin with gzip magic bytes (\x1f\x8b) and decompress to anomalously large sizes.
  • Process: PHP-FPM or web server worker processes terminating unexpectedly or restarting frequently, correlated with file upload activity (GitHub Advisory).

Mitigation and workarounds

Upgrade to one of the patched versions: 1.30.6, 2.1.18, 2.4.7, 3.10.7, or 5.8.1. The fix passes $this->maxLength (derived from PHP's memory_limit ini setting, capped at one-quarter of available memory) as the second argument to gzdecode(), enforcing a bounded decompression limit. Applications can also call $reader->setMaxLength(int) to configure a custom limit. As a short-term workaround where upgrading is not immediately possible, restrict or block .gnumeric file uploads at the application or WAF layer (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