Vulnerability GHSA-rf6f-7fwh-wjgh
Summary
Prototype Pollution via parse() in NodeJS flatted
Details
Root Cause
File: esm/index.js:29 (identical in cjs/index.js)
const resolver = (input, lazy, parsed, $) => output => {
for (let ke = keys(output), {length} = ke, y = 0; y < length; y++) {
const k = ke[y];
const value = output[k];
if (value instanceof Primitive) {
const tmp = input[value]; // Bug is here
No validation that value is a safe numeric index input is built as a plain Array. JavaScript's property lookup on arrays traverses the prototype chain for non-numeric keys. The key "__proto__" resolves to Array.prototype, which:
- has type "object" → passes the typeof tmp === object guard at line 30
- is not in the parsed Set yet → passes the !parsed.has(tmp) guard.
- The reference to Array.prototype is then enqueued in lazy and later unconditionally assigned to the output object. Impact An attacker can supply a crafted flatted string to parse() that causes the returned object to hold a live reference to Array.prototype, enabling any downstream code that writes to that property to pollute the global prototype chain, potentially causing denial of service or code execution.
Recommended solution Validate that the index string represents an integer within the bounds of input before accessing it:
// Before (vulnerable) const tmp = input[value];
// After (safe) const idx = +value; // coerce boxed String → number const tmp = (Number.isInteger(idx) && idx >= 0 && idx < input.length) ? input[idx] : undefined;
Related Vulnerabilities
Other vulnerabilities affecting the same packages