Attacker-controlled JSON input modifies Object.prototype via __proto__, constructor, or prototype keys.
JavaScript’s prototype chain lets every object inherit from `Object.prototype`. Prototype pollution happens when attacker-controlled input — often from `__proto__`, `constructor`, or `prototype` keys in JSON/YAML parsed from untrusted sources — modifies `Object.prototype` itself. Every object in your application then inherits the attacker’s injected property, bypassing checks that assume unknown properties don’t exist.
// VULNERABLE — user input directly merged into object
const payload = JSON.parse(req.body.data);
const config = { ...defaults, ...payload }; // __proto__ or constructor.prototype pollutes Object.prototype
if (config.isAdmin) { /* bypass auth */ }
// FIXED — sanitize dangerous keys
const payload = JSON.parse(req.body.data);
const FORBIDDEN = ['__proto__', 'constructor', 'prototype'];
const safe = Object.fromEntries(
Object.entries(payload).filter(([k]) => !FORBIDDEN.includes(k))
);
const config = { ...defaults, ...safe };
pool.query(`SELECT * FROM users WHERE id = ${req.params.id}`)