ast/prototype-pollution-merge-user-input
Prototype pollution: deep merge / assign with user-controlled object
What it detects
A deep-merge function (lodash.merge / .mergeWith / .defaultsDeep / .set / .setWith) was called with a source object sourced from req.body, req.query, req.params, req.headers, ctx.request, or `userInput`. An attacker payload `{ "__proto__": { "isAdmin": true } }` pollutes Object.prototype globally on most lodash versions. Either upgrade to a patched version (lodash >= 4.17.20 with prototype-traversal disabled by default), validate the payload shape with Zod / Joi BEFORE merging, or use `Object.create(null)` as the target so the prototype chain isn't reachable.
How it runs
Each file scanned is parsed with the TypeScript Compiler API (via ts-morph). This rule walks the AST looking for the call shape and user-input flow it describes. Skipped on files larger than 200 KB or that fail to parse.
Found a false positive or want this rule tuned? File an issue. You can also suppress per-repo via a .repoguardignore line.