1 · Send a payload through a merge

Pick a payload, choose the vulnerable or hardened deepMerge, and run it into a fresh empty object. Then we probe a brand-new {} to see whether Object.prototype was polluted globally.

Probe: a fresh const probe = {}
Run a merge to inspect…

2 · The gadget — pollution → impact

Pollution alone is silent. The impact comes when existing code reads a property it expects to be absent. Below, two implementations of canEdit(options = {}) are called with an empty options object — watch how the polluted isAdmin flips one of them.

❌ Vulnerable gadget

function canEdit(o = {}) {
  return o.isAdmin === true;
}
canEdit({})
result: false

✅ Hardened gadget

function canEdit(o = {}) {
  return Object.hasOwn(o, 'isAdmin')
    && o.isAdmin === true;
}
canEdit({})
result: false

Pollute via section 1 with isAdmin: true, then watch the vulnerable gadget return true for an empty object — an auth bypass with no script injected.

3 · Object.prototype monitor

Own keys currently sitting on the shared Object.prototype (should be empty when clean).

clean