Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessCraft tiny gzip .gnumeric bomb
-
DeliveryUpload to spreadsheet-processing endpoint
-
ExploitReach Gnumeric::canRead() detection
-
ExecutionUnbounded gzdecode() inflates to ~96 MiB
-
PersistExhaust PHP memory_limit
-
ImpactFatal error crashes worker (DoS)
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V2 - Validation and Business Logic Resource consumption limits
MITRE ATT&CK
1 technique across 1 tactic: Impact The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires that the target application feed an attacker-controlled file into PhpSpreadsheet's Gnumeric reader - either directly via the Gnumeric loader or through automatic file-type detection that calls Gnumeric::canRead()/IOFactory auto-detection - and that the file begin with gzip magic bytes so the vulnerable gzdecode() path is taken. No authentication is required (CVSS PR:N), no user interaction is needed (UI:N), and default configurations are affected because no size cap existed prior to the patch. What LIMITS exploitation: the application must actually accept and process untrusted spreadsheet/.gnumeric uploads (services that never invoke the Gnumeric reader are not exposed), and the effective impact depends on the PHP memory_limit and whether parsing runs in an isolated, restartable worker. The attack yields only denial of service (availability), not code execution or data access. |
| Impact | The CVSS 3.1 vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (7.5, High) is internally consistent with the description: a network-reachable, unauthenticated, low-complexity attack with no user interaction that impacts only availability (no confidentiality or integrity loss). The realistic risk is bounded to denial of service - a crashed PHP worker or fatal memory error, not code execution or data disclosure. Exploitation is highly automatable and requires only the ability to submit a spreadsheet file, so for any service that runs PhpSpreadsheet against untrusted uploads this is a genuine availability priority. No EPSS score and no CISA KEV entry were provided in the input, and no public exploit is identified at time of analysis, so there is no evidence of active or widespread exploitation - the risk is 'easy to trigger if reached' rather than 'currently being exploited.' The one caveat is exposure: the vulnerable code path is only reachable if the application actually accepts and processes attacker-controlled .gnumeric (or auto-detected spreadsheet) files, which limits real-world impact to that subset of deployments. |
| Exploit ScenarioDerived | An attacker uploads a ~98 KB .gnumeric file to a web app, queue worker, document converter, or file-preview service that uses PhpSpreadsheet to detect or import spreadsheets. During Gnumeric::canRead() the gzip payload inflates to ~96 MiB, exceeding the PHP memory_limit and killing the worker with a fatal error; repeating the upload sustains a denial of service. A safe local proof-of-concept exists in the advisory (Docker, --network none), though no public weaponized exploit is identified at time of analysis. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Jul 23, 2026
Denial-of-service in PhpSpreadsheet's Gnumeric reader lets remote attackers crash PHP worker processes by uploading a tiny gzip-compressed .gnumeric file that decompresses to hundreds of megabytes. The reader's Gnumeric::canRead() calls gzdecode() with no decompressed-size cap during routine file-type detection, so a ~98 KB payload expanding to ~96 MiB exhausts a 64M memory limit and triggers a fatal error before validation. No public exploit is identified at time of analysis, but a working proof-of-concept is described in the advisory and the CVSS score is 7.5 (High) with A:H impact.
RemediationAI
Upgrade to a patched release for your branch: Vendor-released patch versions are 5.8.1, 3.10.7, 2.4.7, 2.1.18 (and 1.30.6), delivered via commit 85f2556b0bf5269061bf45932ecda8a128d81750. The fix computes a maxLength from the PHP memory_limit (one quarter of it) and passes it to gzdecode($contents, $this->maxLength), and exposes a setMaxLength() method so applications can tighten the cap; run composer update phpoffice/phpspreadsheet to the fixed version for your major line. If you cannot patch immediately, apply compensating controls: reject or do not auto-process files with a .gnumeric extension or gzip magic bytes on untrusted upload paths (trade-off: legitimate Gnumeric imports break); enforce a strict maximum compressed upload size and run spreadsheet parsing in an isolated worker with a conservative memory_limit and process/time limits so a crash is contained and recoverable rather than taking down the main application; and avoid calling canRead()/auto-detection on untrusted files where the format is not expected. See the advisory at https://github.com/PHPOffice/PhpSpreadsheet/security/advisories/GHSA-2mrg-gjxq-2gvr and the patch commit at https://github.com/PHPOffice/PhpSpreadsheet/commit/85f2556b0bf5269061bf45932ecda8a128d81750.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in composer, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The affected component is the PHP library PhpSpreadsheet (Composer package phpoffice/phpspreadsheet), specifically the Gnumeric reader that ingests .gnumeric spreadsheet files - an XML format that is commonly gzip-compressed. In src/PhpSpreadsheet/Reader/Gnumeric.php, gzfileGetContents() reads the whole file with file_get_contents(), detects gzip magic bytes, and calls gzdecode($contents) with no output-length argument, so the entire payload is inflated into memory before any XML scanning or structural validation occurs. This is a textbook CWE-400 (Uncontrolled Resource Consumption), realized here as a classic decompression bomb / gzip amplification: the attacker controls the compression ratio, so a small input forces an unbounded allocation. The same unbounded path is reachable from canRead(), listWorksheetNames(), listWorksheetInfo(), and load(), and some call sites decompress the file more than once, compounding the cost.
Know when PHP gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Remote, unauthenticated, no-interaction file upload triggers unbounded decompression with availability-only impact, so AV:N/AC:L/PR:N/UI:N and C:N/I:N/A:H.
Primary rating from Vendor (https://github.com/PHPOffice/PhpSpreadsheet).
CVSS VectorVendor: https://github.com/PHPOffice/PhpSpreadsheet
DescriptionCVE.org
Summary
PhpSpreadsheet's Gnumeric reader reads attacker-supplied .gnumeric files into memory and, when the file starts with gzip magic bytes, calls gzdecode() on the full compressed contents without enforcing a decompressed-size limit. A very small compressed .gnumeric file can expand to data larger than the PHP memory limit and crash the process during Gnumeric::canRead() before the file is rejected or fully parsed.
This is reachable through normal file-type detection and Gnumeric loading paths, so applications that accept attacker-controlled spreadsheet uploads can suffer denial of service.
Vulnerability details
Gnumeric::canRead() invokes gzfileGetContents() before deciding whether the file is a valid Gnumeric spreadsheet:
src/PhpSpreadsheet/Reader/Gnumeric.php:80-90calls$this->gzfileGetContents($filename)fromcanRead().src/PhpSpreadsheet/Reader/Gnumeric.php:105-115callscanRead()and then reads the expanded contents again for worksheet-name listing.src/PhpSpreadsheet/Reader/Gnumeric.php:253-265callscanRead()and then reads the expanded contents again for full loading.
The vulnerable expansion is in gzfileGetContents():
src/PhpSpreadsheet/Reader/Gnumeric.php:187-190reads the entire input file into$contentswithfile_get_contents().src/PhpSpreadsheet/Reader/Gnumeric.php:192-197detects gzip magic bytes and callsgzdecode($contents)without a decompressed-size cap.src/PhpSpreadsheet/Reader/Gnumeric.php:204-205scans the expanded data only after decompression has already completed.
Because decompression occurs before XML scanning or structural validation, a tiny gzip payload can force large memory allocation even if the resulting XML is meaningless or invalid.
Impact
A small .gnumeric upload can crash a PHP worker during spreadsheet type detection or import. This can cause denial of service in web applications, queue workers, preview services, document converters, or any service that runs PhpSpreadsheet against untrusted spreadsheet files.
In the local reproduction below, a 97,811-byte file expands to about 96 MiB and crashes Gnumeric::canRead() under memory_limit=64M at Reader/Gnumeric.php:195.
Safe local proof of concept
This proof of concept uses only Docker with --network none; it creates the compressed payload inside the container and does not contact external infrastructure.
docker run --rm --network none -i \
-v /home/sondt23/Github/CVE/ares/github-repo/PhpSpreadsheet:/app \
-w /app ghcr.io/typo3/core-testing-php82:1.15 sh <<'SH'
set -eu
php -r '
$prefix = "<?xml version=\"1.0\"?><gnm:Workbook xmlns:gnm=\"http://www.gnumeric.org/v10.dtd\">";
$suffix = "</gnm:Workbook>";
$payload = $prefix . str_repeat("A", 96 * 1024 * 1024) . $suffix;
$gz = gzencode($payload, 9);
file_put_contents("/tmp/bomb.gnumeric", $gz);
printf("compressed_size=%d expanded_size=%d\n", filesize("/tmp/bomb.gnumeric"), strlen($payload));
'
php -d memory_limit=64M -d display_errors=1 -r '
require "/app/vendor/autoload.php";
$r = new PhpOffice\PhpSpreadsheet\Reader\Gnumeric();
var_dump($r->canRead("/tmp/bomb.gnumeric"));
' 2>&1 || true
SHObserved output:
compressed_size=97811 expanded_size=100663390
PHP Fatal error: Allowed memory size of 67108864 bytes exhausted (tried to allocate 50291378 bytes) in /app/src/PhpSpreadsheet/Reader/Gnumeric.php on line 195
PHP Stack trace:
PHP 1. {main}() Command line code:0
PHP 2. PhpOffice\PhpSpreadsheet\Reader\Gnumeric->canRead($filename = '/tmp/bomb.gnumeric') Command line code:4
PHP 3. PhpOffice\PhpSpreadsheet\Reader\Gnumeric->gzfileGetContents($filename = '/tmp/bomb.gnumeric') /app/src/PhpSpreadsheet/Reader/Gnumeric.php:84
PHP 4. gzdecode(...) /app/src/PhpSpreadsheet/Reader/Gnumeric.php:195Suggested remediation
- Do not decompress gzip data with unbounded
gzdecode()for untrusted.gnumericfiles. - Stream decompression with a strict maximum output-size limit before allocating the full expanded XML.
- Enforce a configurable maximum compressed size and maximum decompressed size for Gnumeric files.
- Ensure
canRead(),listWorksheetNames(),listWorksheetInfo(), andload()share bounded decompression logic and avoid decompressing the same file repeatedly. - Fail closed with a recoverable
Reader\Exceptionwhen limits are exceeded, rather than allowing a PHP fatal memory error.
Articles & Coverage 2
Executive ViewAI
PhpSpreadsheet, a widely-used PHP library for spreadsheet file processing, contains a denial-of-service vulnerability in its Gnumeric file reader that allows remote attackers to crash application worker processes by uploading specially crafted compressed files. Organizations relying on PhpSpreadsheet for file-upload functionality face service unavailability and potential business process interruption. This HIGH-severity vulnerability requires immediate patching to prevent resource exhaustion and maintain application availability.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.
In PHP versions 7.1.x below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 in certain configurations of FPM setup it
sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
The '/common/download_agent_installer.php' script in the Quest KACE System Management Appliance 8.0.318 is accessible by
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
EUVD-2026-49952
GHSA-2mrg-gjxq-2gvr
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB