High

xlsx CVE-2023-30533 · CVE-2024-22363

Prototype pollution and ReDoS in SheetJS xlsx on file read.

The problem

xlsx <= 0.18.5 on npm (the last npm-published release) is affected by CVE-2023-30533, CVE-2024-22363 (CWE-1321 Prototype Pollution / CWE-1333 ReDoS). The published package has no fix available — exactly what npm audit reports. Two vulnerabilities are reachable when `XLSX.read()` parses an attacker-supplied spreadsheet. CVE-2023-30533: a crafted (threaded) comment whose cell `ref` is `__proto__` causes `sheet[ref]` to resolve to `Object.prototype`, which is then mutated — polluting every object in the process. CVE-2024-22363: a crafted `docProps/core.xml` with many unclosed property tags triggers catastrophic backtracking in the core-property regex (a ~2 MB file takes ~50 seconds to parse, a denial of service).

The fix — drop-in, no code changes

Add an overrides entry so every direct and transitive dependency on xlsx resolves to the patched fork, then reinstall:

{
  "overrides": {
    "xlsx": "npm:@keep-lts/xlsx@^0.18.6"
  }
}

Equivalent for Yarn: use resolutions. The public API is unchanged — nothing else to do.

✓ Live on npm: @keep-lts/xlsx  ·  or install directly: npm i @keep-lts/xlsx

What we changed

Prototype pollution: `sheet_insert_comments` now returns early when `decode_cell(comment.ref)` yields negative row/column, so a non-address ref such as `__proto__` can never reach `sheet[comment.ref]`. ReDoS: `parse_core_props` now locates each property tag with `String#indexOf` (`str_match_xml`) instead of a `([\s\S]*?)` regex that re-scanned from every opening tag. Both are direct ports of SheetJS's own fixes; a cross-version equivalence test confirms legitimate files parse identically to upstream 0.18.5.

Proof of concept (the vulnerability)

const XLSX = require('xlsx');
// 1) prototype pollution
XLSX.read(fs.readFileSync('threaded_comment_bad.xlsx')); // sets Object.prototype.c on 0.18.5
// 2) ReDoS: a docProps/core.xml with 128k unclosed <dcterms:created> tags
XLSX.read(crafted_buffer, { type: 'buffer' }); // ~50s on 0.18.5, ~17ms when patched
Patched version@keep-lts/xlsx@0.18.6
Weekly downloads (affected pkg)10,557,539
Regression tests6 passing
LicenseApache-2.0

How we keep it trustworthy

Full advisory and changelog ship inside the package (SECURITY.md, CHANGELOG.md).

← All maintained packages