Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-59932

CVE-2026-59932: PhpSpreadsheet DOS Vulnerability

CVE-2026-59932 is a denial of service vulnerability in PhpSpreadsheet that allows attackers to crash applications using malicious Gnumeric files. This article covers the technical details, affected versions, and mitigation.

Published:

CVE-2026-59932 Overview

CVE-2026-59932 is a denial of service vulnerability in PhpSpreadsheet, a pure PHP library for reading and writing spreadsheet files. The Gnumeric reader calls gzdecode() on attacker-supplied .gnumeric files without enforcing a decompressed-size limit. A small compressed file can expand to data larger than the PHP memory limit and crash the process during Gnumeric::canRead(). The flaw is reachable through normal file-type detection paths, so any application accepting spreadsheet uploads is exposed. The issue is tracked under [CWE-400] Uncontrolled Resource Consumption.

Critical Impact

A crafted .gnumeric decompression bomb can exhaust PHP memory and crash the worker process, producing denial of service for any application accepting spreadsheet uploads.

Affected Products

  • PhpSpreadsheet versions 4.0.0 through 5.8.0, 3.3.0 through 3.10.6, 2.2.0 through 2.4.6, 2.0.0 through 2.1.17
  • All PhpSpreadsheet releases up to and including 1.30.5
  • PHP applications that accept attacker-controlled spreadsheet uploads and use the Gnumeric reader or file-type auto-detection

Discovery Timeline

  • 2026-07-28 - CVE-2026-59932 published to NVD
  • 2026-07-29 - Last updated in NVD database

Technical Details for CVE-2026-59932

Vulnerability Analysis

The vulnerability resides in the Gnumeric reader class within PhpSpreadsheet. When the library evaluates an uploaded file, Gnumeric::canRead() inspects the first bytes and, if it detects gzip magic bytes, it decompresses the entire payload using PHP's gzdecode() function. No maximum decompressed size is enforced before this call executes.

An attacker can craft a very small gzip-compressed .gnumeric file that expands to gigabytes of data. The PHP process attempts to allocate memory for the full decompressed buffer and hits the configured memory_limit, terminating with a fatal error. The crash occurs during file-type detection, so the file is never actually parsed or rejected by higher-level logic.

Root Cause

The root cause is missing input validation on decompressed output length. The reader trusts the compressed archive's expanded size and calls gzdecode() on the full contents in a single operation. This maps to [CWE-400] Uncontrolled Resource Consumption. The fixed versions introduce a maxLength property and a LENGTH_MULTIPLIER constant to cap decompression at a configurable ceiling.

Attack Vector

Exploitation requires no authentication, no user interaction, and only network access to any endpoint that accepts spreadsheet uploads. The attacker submits a small crafted .gnumeric file to a form, API, or import handler that invokes PhpSpreadsheet's IOFactory::load() or an equivalent auto-detection path. The crash occurs on the server-side worker before any business logic runs.

php
// Security patch in src/PhpSpreadsheet/Reader/Gnumeric.php
         ],
     ];
 
+    protected int $maxLength;
+
+    private const LENGTH_MULTIPLIER = [
+        'G' => 1024 * 1024 * 1024,
+        'M' => 1024 * 1024,
+        'K' => 1024,
+    ];
+
     /**
      * Create a new Gnumeric.
      */
// Source: https://github.com/PHPOffice/PhpSpreadsheet/commit/85f2556b0bf5269061bf45932ecda8a128d81750

The patch adds a $maxLength property and a size-multiplier constant. The reader now enforces a decompressed-size ceiling instead of blindly calling gzdecode() on the full payload.

Detection Methods for CVE-2026-59932

Indicators of Compromise

  • Recurring PHP fatal errors referencing Allowed memory size exhausted during calls to gzdecode() or Gnumeric::canRead().
  • Web server or FPM worker crashes correlated with uploads of .gnumeric or unknown-typed spreadsheet files.
  • Small uploaded files (a few KB) that trigger multi-gigabyte memory allocations in PHP processes.

Detection Strategies

  • Inspect application logs for PHP Fatal error: Allowed memory size entries whose stack traces reference PhpOffice\PhpSpreadsheet\Reader\Gnumeric.
  • Add pre-processing checks that reject .gnumeric uploads exceeding a defined compressed-size threshold or an unrealistic compression ratio.
  • Use dependency scanning (Composer audit, GitHub Dependabot, Snyk) to flag PhpSpreadsheet versions vulnerable to GHSA-2mrg-gjxq-2gvr.

Monitoring Recommendations

  • Alert on abnormal PHP worker restart rates and out-of-memory kills on servers running upload endpoints.
  • Monitor upload endpoints for repeated submissions from the same source that trigger 5xx responses immediately after file receipt.
  • Track spikes in decompression ratio (uploaded bytes vs. process memory delta) as a behavioral signal for compression-bomb attacks.

How to Mitigate CVE-2026-59932

Immediate Actions Required

  • Upgrade PhpSpreadsheet to a patched release: 5.8.1, 3.10.7, 2.4.7, 2.1.18, or 1.30.6.
  • Audit application code paths that call IOFactory::load() or invoke Gnumeric explicitly on user-supplied files.
  • Restrict accepted upload MIME types and reject .gnumeric files if the format is not required by business logic.

Patch Information

The maintainers released fixes across all supported branches. See the release notes for 5.8.1, 3.10.7, 2.4.7, 2.1.18, and 1.30.6. The corresponding upstream commit introduces the $maxLength guard.

Workarounds

  • Enforce a strict maximum upload size on the web server or reverse proxy for spreadsheet endpoints.
  • Disable Gnumeric auto-detection by explicitly instantiating a non-Gnumeric reader (for example, Xlsx or Csv) instead of using IOFactory::load().
  • Isolate spreadsheet parsing in a short-lived worker with a low memory_limit so crashes do not affect the main application process.
bash
# Update via Composer to a patched release
composer require phpoffice/phpspreadsheet:^5.8.1

# Verify installed version
composer show phpoffice/phpspreadsheet | grep versions

# Optional: cap PHP memory for isolated import workers
# php.ini for the spreadsheet-import pool
# memory_limit = 256M
# upload_max_filesize = 8M
# post_max_size = 8M

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.