Prototype Pollution Security Check (CWE-1321)

SkillDev tools

Detects JavaScript deep-merges or property assignment from user input that can

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Prototype Pollution Security Check (CWE-1321) skill

What this skill tells your AI

The instructions your AI receives, as published by thejefflarson/soundcheck in .claude/skills/prototype-pollution/SKILL.md and read by ahel’s review.

What this checks

Protects against prototype pollution in JavaScript/TypeScript where an attacker injects properties like __proto__ or constructor.prototype through user input, modifying the prototype chain of all objects. Exploitation leads to property injection, auth bypass, and remote code execution in some frameworks.

Vulnerable patterns

  • Deep merge of user input into a config or options object using a library helper that recurses through __proto__.
  • Object.assign or spread of a parsed JSON body into a target object — the __proto__ key is copied as a regular property and walked by the engine.
  • Custom recursive merge that iterates source keys with no filter — __proto__ and constructor.prototype are merged in alongside everything else.
  • Dynamic property assignment where both the key and the value come from user input, with no key validation.

Fix immediately

Flag the vulnerable code and explain the risk. Then suggest a fix that establishes these properties. The audited file is JavaScript or TypeScript by definition, so the principles translate directly — apply them using the project's existing utility library and module conventions.

  1. Any recursive merge, clone, or property copy on user input filters the dangerous keys__proto__, constructor, prototype. The filter runs before assignment, not after; a post-hoc delete does not help because the prototype chain was already mutated.
  2. Dynamic property assignment from user input validates the key against a blocklist, or sidesteps the issue by using a Map. A Map has no prototype-chain exposure; object indexing does.
  3. Config and lookup objects use a null-prototype object when keys come from input. An object created with no prototype cannot be polluted because there is no prototype chain to reach.
  4. Library deep-merge helpers (_.merge, _.set, $.extend(true, …)) on untrusted input are replaced with key-filtered wrappers or safe alternatives. The issue is library-version-dependent, so relying on patched versions is fragile; filter at the call site.

When iterating source keys, use the own-keys iterator (e.g. Object.keys), never the prototype-walking variant.

Verification

  • No deep merge, clone, or recursive property copy on user-controlled input proceeds without filtering __proto__, constructor, and prototype keys
  • Dynamic property assignment from user input validates the key against a blocklist or uses Map instead
  • If a library deep-merge helper is used, it is replaced or wrapped with a key filter before being applied to untrusted input
  • Iteration uses an own-keys iterator, not a prototype-walking one

References

Signals

GitHub stars
20
Last commit
Jul 2026
Advanced
Catalog kind
skill
Gateway key
prototype-pollution-thejefflarson
Source
github.com/thejefflarson/soundcheck