+ "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",
0 commit comments