Imagine a hotel where every room key is cut from a master template. When a guest checks in, the front desk hands them a key that opens only their room. Simple enough. Now imagine a guest who, during check-in, sneaks a tiny modification into the key-cutting machine itself — changing the template so that every new key cut from that moment on also opens the manager's office, the safe, and the server room.
The guest didn't break a lock. They didn't clone anyone's key. They changed the factory that makes all keys.
That factory is JavaScript's Object.prototype. And the attack is called Prototype Pollution.
Top comments (2)
It won't affect ALL objects.
The analogy nails the mechanism, but imo the scary part isn't the pollution itself — it's that it stays inert until some downstream code reads a property it never set as a decision. Stuff like
if (opts.isAdmin)or a spawn call that pullsoptions.shellfrom a merged config: nobody wrote those keys, they just resolve up through the polluted prototype. That's why guarding the merge/assign function alone doesn't save you — the real fix is making security-relevant lookups use own-property checks (or null-prototype objects viaObject.create(null)for anything holding user-controlled keys).Object.freeze(Object.prototype)works as a backstop too, but it's a blunt instrument that quietly breaks libs that expect to assign to the prototype.