Lodash versions 4.17.23 and earlier expose applications to prototype pollution through a bypass in the _.unset and _.omit functions. Attackers delete properties from core prototypes like Object.prototype, Number.prototype, and String.prototype. The patch lands in 4.18.0. This hits lodash, lodash-es, and lodash-amd packages, which together rack up over 50 million weekly npm downloads.
Prototype pollution lets attackers tamper with JavaScript’s shared prototypes. Normally, this means injecting malicious properties that poison every object in the app. Here, the vulnerability limits damage to deletions—no overwrites. Delete Object.prototype.toString, and suddenly JSON.stringify chokes on plain objects, or for...in loops skip expected properties. In Node.js servers or browser apps, this breaks parsing, logging, or serialization without warning.
Technical Breakdown
The root traces to CVE-2025-13465, patched earlier by blocking string-based paths to sensitive keys like __proto__ or constructor. Lodash’s path resolution in _.unset and _.omit handles both strings (e.g., '__proto__.toString') and arrays (e.g., ['__proto__', 'toString']). The prior fix checked only string segments, leaving array paths exposed.
An attacker supplies a crafted path array. Lodash traverses it recursively, reaching prototypes:
// Vulnerable code example (Lodash <= 4.17.23)
const _ = require('lodash');
let victim = {}; // Attacker controls path
let maliciousPath = ['__proto__', 'toString'];
_.unset(victim, maliciousPath);
// Now Object.prototype.toString is gone
console.log(Object.prototype.toString); // undefined
console.log({}.toString()); // TypeError: Cannot convert undefined to object
This deletes the property entirely from the prototype chain. Test it yourself in a Node REPL with vulnerable Lodash. The same works for _.omit(victim, maliciousPath), which omits along the path. No overwrites happen—original getters/setters stay intact unless deleted.
Lodash maintainers confirmed the issue via GitHub advisory GHSA-xxjr-mmjv-4gpg. Lodash 4.x, released in 2016, remains widely used despite version 5.0.0 dropping in April 2024. Legacy codebases stick to 4.x for compatibility, especially in enterprise Node apps or bundled frontend builds.
Real-World Risks and Why It Matters
Impact hinges on user input feeding _.unset or _.omit. Rare in sanitized APIs, but common in dynamic config loaders, query parsers, or deserializers from untrusted JSON. A single vulnerable endpoint turns a prototype deletion into app crashes.
Consider scale: Lodash powers millions of projects—Angular, React apps, Express servers. Snyk scans show 4.17.x in 10-15% of JavaScript deps. Deletions disrupt subtly: Error.prototype.stack gone breaks stack traces; Number.prototype.toFixed missing tanks financial calcs. In crypto or finance apps, this corrupts output without alerts.
Past Lodash vulns (e.g., CVE-2021-23337) enabled full pollution, leading to RCE in chains. This one’s milder but evades audits missing array paths. No public exploits yet, but proof-of-concepts circulate on GitHub. Browser sandboxes limit blast radius, but Node servers run full risk.
Skeptical take: Deletions beat full writes, and most apps avoid raw user paths in Lodash. Still, false security from the prior patch breeds complacency. If your dep tree includes vulnerable Lodash, assume exposure until upgraded.
Fixes and Next Steps
Upgrade to 4.18.0 immediately:
$ npm update lodash lodash-es lodash-amd
# Or pin: npm install lodash@4.18.0
Audit your tree:
$ npm ls lodash
$ yarn why lodash
No workarounds exist—deep clones or path validation add overhead and miss edge cases. Long-term, migrate off Lodash 4.x. Native JS covers 80% of utils: use Reflect.deleteProperty for unsets, structuredClone for deep copies. Ramda or lodash/fp offer functional alternatives without proto risks.
Scan repos with npm audit or tools like Snyk. Test post-upgrade: Restore prototypes if needed via Object.setPrototypeOf. This patch closes the gap, but Lodash’s history demands vigilance—treat utils libs as high-risk deps.