#6263·lodash

baseUnset: __proto__ guard checks ownership on the root object, not the current node

Author: utkarsh2102Created Jul 25, 2026Updated Sep 5, 2026

Hi!

Whilst trying to backport the patches for some security issues in Debian, we discovered an interesting problem.

The prototype-pollution guard added to baseUnset in 4.18.0 (commit fe8d32e) can be bypassed for __proto__ when the root object owns a __proto__ key.

The guard walks the path but never advances object:

    while (++index < length) {
      var key = toKey(path[index]);
      if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
        return false;
      }
      ...
    }

object is the original root the whole time, so hasOwnProperty.call(object, '__proto__') only ever inspects the root — not the node at the current position in the path. If the root owns a __proto__ key, the __proto__ check is effectively disabled for every segment, and a deeper __proto__ reaches a nested object's real prototype.

An own __proto__ key is easy to get from untrusted input: JSON.parse('{"__proto__":1}') creates a genuine own data property (it doesn't trigger the setter). Parsing attacker JSON and then running _.unset / _.omit on it with a path is a normal pattern.