Zennoxa Shield
Rules / JavaScript / TypeScript
SHIELD-JS-007

Prototype pollution via merge/assign

highJavaScript / TypeScriptCWE-1321CVSS 7.5

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.

SHIELD-JS-007: Prototype pollution via merge/assign — Zennoxa Shield