flawopen.com/Prototype Pollution/lodash.merge()
In current versions, yes — lodash added guards against __proto__, constructor and prototype keys after a series of advisories. In older versions, no: merge, mergeWith, defaultsDeep, set and setWith were among the most commonly exploited sinks for this bug class anywhere in the ecosystem.
// lodash < 4.17.21 (and several // earlier advisory boundaries) const _ = require('lodash'); app.post('/config', (req, res) => { _.merge(settings, req.body); }); // POST {"__proto__":{"isAdmin":true}} // → every object now has isAdmin // _.set() took a path, which was worse: _.set(obj, req.query.path, req.query.val); // path = "__proto__.isAdmin"
# 1. Upgrade — this is the real fix npm ls lodash npm install lodash@latest // 2. Never pass a request body straight // into a deep merge. Pick fields: _.merge(settings, { theme: req.body.theme, locale: req.body.locale, }); // 3. Never let a user supply the PATH // argument to set()/setWith().
Nothing about lodash's implementation was unusually careless — the vulnerability is inherent to "recursively copy arbitrary keys from one object onto another", which is precisely what these functions are for. lodash drew attention because it is one of the most depended-upon packages in the ecosystem, so a single unguarded merge appeared in an enormous number of applications, frequently with a request body on the source side.
The guards added upstream skip the three dangerous key names. That closes the direct route, but it does not change the underlying advice: passing untrusted input wholesale into a deep merge remains a poor pattern even on a patched version, because it also silently accepts every other field an attacker chooses to send.
npm ls lodash
npm audit
Check transitive copies too — a direct upgrade does not move a nested dependency that pins an old version. npm ls shows every copy in the tree and which package pulled it in.
Across the various advisories: merge, mergeWith, defaultsDeep, set, setWith, and zipObjectDeep. Consult the advisory database for the exact version boundary per function rather than assuming one cutoff covers all of them.
It will not pollute the prototype on a current version. It will still copy every other attacker-supplied key onto your object, which is a mass-assignment problem in its own right. Select fields explicitly.
Many have had the same advisory. The pattern, not the package, is the risk — evaluate any deep-merge or object-path utility the same way.