Prototype pollution

Slap yourself if

You believe objects are isolated containers and **proto** is just a weird edge case.

Why this exists

Prototype pollution exists because JavaScript treats object inheritance as a live, mutable chain. Combined with dynamic property assignment and user-controlled input, this turns shared prototypes into a global attack surface.

Mental model

Every object lookup is a walk up a shared prototype chain. If an attacker can mutate any link in that chain, they can influence behavior far outside the original data boundary.

  • User-controlled keys are assigned onto plain objects.
  • Special keys like **proto**, constructor, or prototype alter inheritance instead of data.
  • Mutations land on shared prototypes such as Object.prototype.
  • Unrelated objects suddenly gain or override properties.
  • Application logic changes without touching the original code path.
  • Blindly merging objects from external input.
  • Assuming JSON.parse output is safe by default.
  • Using deep merge utilities without understanding edge cases.
  • Treating Object.create(null) as optional instead of intentional.

Prototype pollution is a vulnerability where attacker-controlled object properties mutate shared prototypes, causing unexpected behavior across the application without direct access to affected objects.

  • Deep merge helpers with untrusted input
  • for...in loops over user objects
  • Relying on hasOwnProperty checks inconsistently
  • Assuming framework abstractions eliminate object risks

Deep dive

Requires Pro

Premium deep dives include more internals, more scars.

How prototype mutation actually propagates

From data corruption to code execution

Why JavaScript can’t realistically fix this

Diagnosing pollution in large codebases

Common misconceptions candidates reveal