Skip to content

Commit 99ff3cc

Browse files
committed
[NEW] CVE-2026-38359: xlsx ZIP Header Memory Allocation DoS
1 parent d0f8161 commit 99ff3cc

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"schema_version": "1.4.0",
3+
"id": "xlsx-zip-bomb-cve-2026-38359",
4+
"modified": "2026-05-07T00:00:00Z",
5+
"published": "2026-05-07T00:00:00Z",
6+
"aliases": [
7+
"CVE-2026-38359"
8+
],
9+
"summary": "xlsx (SheetJS Community Edition): Unvalidated decompression size from ZIP local file headers leads to memory exhaustion DoS",
10+
"details": "## Summary\n\nSheetJS xlsx Community Edition (all versions including 0.18.5, unmaintained since 2022) reads the uncompressed-size field directly from ZIP local file headers without validation and passes it to `Buffer.allocUnsafe()`. An attacker can craft an XLSX file with arbitrary declared decompression sizes (e.g., 1 GB per entry in a 10 KB file), causing multi-gigabyte synchronous memory allocations that result in out-of-memory crashes.\n\n**The package is unmaintained.** Users should migrate to `xlsx-js-style` or `exceljs`.\n\n## Vulnerable code\n\n**Step 1 — Read uncompressed size from ZIP local file header (`xlsx.js:2670`):**\n```javascript\n// Offset 18-22: Compressed size (4 bytes)\nvar _csz = buf.read_shift(4);\n// Offset 22-26: Uncompressed size (4 bytes) — ATTACKER CONTROLLED\nvar _usz = buf.read_shift(4); // NO VALIDATION\n```\n\n**Step 2 — Direct allocation without limits (`xlsx.js:2529`):**\n```javascript\nvar outbuf = new_unsafe_buf(usz ? usz : (1<<18));\n// → Buffer.allocUnsafe(usz) — Direct allocation from attacker value\n// No maximum size check\n// No compression ratio validation\n```\n\n**Weak consistency check (`xlsx.js:2700-2701`):**\n```javascript\nif(csz !== _csz) throw new Error(\"CSZ\");\nif(usz !== _usz) throw new Error(\"USZ\");\n```\n\nThis only verifies that the local file header matches the central directory header. Both are attacker-controlled, so the attacker simply sets both to the same malicious value — providing no protection.\n\n## Attack mechanism\n\nThe attacker modifies ZIP local file headers to set the uncompressed-size field (bytes 22-26) to arbitrarily large values. The parser reads this attacker-controlled value and passes it directly to `Buffer.allocUnsafe()`, triggering multi-gigabyte synchronous memory allocations.\n\n**Required payload:** ~10 KB XLSX file with modified ZIP headers declaring 10 GB total uncompressed size.\n**Result:** Out-of-memory process termination.\n\n## Impact\n\nAny application that processes untrusted XLSX files using SheetJS Community Edition is vulnerable. Attack scenarios:\n\n- Web application file upload endpoints\n- Email gateway scanners\n- REST/GraphQL APIs with Excel import\n- Cloud storage with automatic file processing\n- CI/CD pipelines that process Excel files\n\n## Mitigation\n\nNo patch will be released — SheetJS Community Edition is unmaintained.\n\n**Migrate to:**\n- `xlsx-js-style`\n- `exceljs`\n\nIf migration is not immediately possible:\n- Set strict file size limits BEFORE invoking `XLSX.read()`\n- Process parsing in a memory-limited subprocess (e.g. Node.js `--max-old-space-size`)\n- Pre-scan ZIP local file headers and reject files with implausible uncompressed sizes\n- Use a WebAssembly-sandboxed parser",
11+
"severity": [
12+
{
13+
"type": "CVSS_V3",
14+
"score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "xlsx"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
}
30+
]
31+
}
32+
],
33+
"database_specific": {
34+
"last_known_affected_version_range": "<= 0.18.5"
35+
}
36+
}
37+
],
38+
"references": [
39+
{
40+
"type": "ADVISORY",
41+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-38359"
42+
},
43+
{
44+
"type": "PACKAGE",
45+
"url": "https://github.com/SheetJS/sheetjs"
46+
},
47+
{
48+
"type": "WEB",
49+
"url": "https://www.npmjs.com/package/xlsx"
50+
},
51+
{
52+
"type": "WEB",
53+
"url": "https://www.npmjs.com/package/xlsx-js-style"
54+
},
55+
{
56+
"type": "WEB",
57+
"url": "https://www.npmjs.com/package/exceljs"
58+
},
59+
{
60+
"type": "WEB",
61+
"url": "https://cwe.mitre.org/data/definitions/400.html"
62+
},
63+
{
64+
"type": "WEB",
65+
"url": "https://cwe.mitre.org/data/definitions/409.html"
66+
},
67+
{
68+
"type": "WEB",
69+
"url": "https://en.wikipedia.org/wiki/Zip_bomb"
70+
}
71+
],
72+
"database_specific": {
73+
"cwe_ids": [
74+
"CWE-400",
75+
"CWE-409"
76+
]
77+
}
78+
}

0 commit comments

Comments
 (0)