Rules / JavaScript / TypeScript
SHIELD-JS-007
Prototype pollution via merge/assign
What it detects
Merging user-controlled objects into a target without key filtering can pollute Object.prototype.
How to fix
Sanitize object keys before merging. Use Object.create(null) for dictionaries.
Vulnerable — Shield flags thismerge.js
// Deep-merge user-supplied JSON into app config
function merge(target, source) {
for (const key in source) {
if (typeof source[key] === "object" && source[key] !== null) {
if (!target[key]) target[key] = {};
merge(target[key], source[key]); // a "__proto__" key pollutes Object.prototype
} else {
target[key] = source[key];
}
}
return target;
}Fixed — scans cleanmerge.js
// Deep-merge with key filtering; dictionary has a null prototype
function merge(target, source) {
const out = Object.create(null);
for (const key of Object.keys(source)) {
if (key === "constructor" || key.startsWith("__")) continue;
out[key] =
typeof source[key] === "object" && source[key] !== null
? merge(target[key] || {}, source[key])
: source[key];
}
return Object.assign(target, out);
}Both snippets are verified against the shipped scanner: the vulnerable one triggers SHIELD-JS-007, the fixed one does not.