Prototype Pollution Explained

TL;DR

Prototype pollution is a JavaScript-specific bug where attackers inject properties straight into Object.prototype, so every object in the app inherits them. It's not exotic: unsafe object merging or a bad path assignment is usually all it takes. The fallout ranges from a stray property to a full authentication bypass, or in the worst case, remote code execution.

How Prototype Pollution Works

Polluting the prototype
// Vulnerable merge function
function merge(target, source) {
  for (let key in source) {
    if (typeof source[key] === 'object') {
      target[key] = merge(target[key] || {}, source[key]);
    } else {
      target[key] = source[key];
    }
  }
  return target;
}

// Attacker sends this payload:
const malicious = JSON.parse('{"__proto__": {"isAdmin": true}}');

merge({}, malicious);

// Now ALL objects have isAdmin!
const user = {};
console.log(user.isAdmin);  // true!

Attack Vectors

  • __proto__ - Direct prototype access
  • constructor.prototype - Through constructor
  • Nested path assignment: a.b.c where b is __proto__

Real-World Impact

Authentication bypass example
// Somewhere in your code:
if (user.role === 'admin') {
  // Grant admin access
}

// After prototype pollution with {"__proto__": {"role": "admin"}}
// Every object now has role: 'admin'
// All users get admin access!

Prevention

Safe practices
// 1. Use Object.create(null) for untrusted data
const safe = Object.create(null);  // No prototype!

// 2. Block dangerous keys
const BLOCKED = ['__proto__', 'constructor', 'prototype'];

function safeMerge(target, source) {
  for (let key in source) {
    if (BLOCKED.includes(key)) continue;
    // ... rest of merge
  }
}

// 3. Use Map instead of plain objects
const data = new Map();

// 4. Freeze the prototype (defense in depth)
Object.freeze(Object.prototype);

Which libraries are vulnerable?

Many utility libraries had prototype pollution issues including lodash, jQuery extend, and various merge/deep-clone libraries. Check npm audit and update regularly.

Can this lead to RCE?

Yes, under the right conditions. If a polluted property ends up in eval, child_process, or a template engine, that's a straight line to code execution. Several real CVEs exist for this.

Detect Prototype Pollution

Our scanner identifies code patterns vulnerable to prototype pollution.

Vulnerability Guides

Prototype Pollution Explained