# Prototype Pollution via constructor.prototype Path Bypassing __proto__-Only Filters

- **Severity:** High
- **Signature ID:** `2aee278c-72d8-4233-affa-b403a11ceb2e`
- **MITRE ATLAS:** AML.T0043 (Craft Adversarial Data)
- **OWASP:** ASI05 (Cascading Failures in Multi-Agent Systems), LLM05 (Improper Output Handling)

## Summary

Some tools that sanitize incoming JSON only block a literal '__proto__' key, assuming that stops attackers from tampering with shared object behavior. This rule catches a bypass where the attacker instead uses a key like 'constructor.prototype.isAdmin', which reaches the exact same shared object behavior through a different path the filter never checks.

## How the attack works

An attacker crafts a JSON object or code snippet containing a key shaped like 'constructor.prototype.<field>' instead of '__proto__.<field>'. When a vulnerable object-merging or 'set' utility processes this payload, it walks obj.constructor to Object, then Object.prototype, and writes the attacker's value there. Because the sanitizer only special-cased the literal string '__proto__', this traversal path slips through untouched. The write pollutes Object.prototype globally, meaning every object in the running process can inherit the attacker's injected field, such as isAdmin=true.

## Why it matters

An attacker can corrupt shared object state across an entire application process, potentially bypassing authorization checks, causing crashes, or altering logic in every part of the app that touches plain objects -- from a single crafted input.

## What you can do

- Patch or update any library performing deep-set/deep-merge operations on user-controlled JSON, especially vendored or older lodash-style utilities.
- Do not rely on filters that block only the literal '__proto__' string; block or reject any key path containing 'constructor.prototype' as well.
- Freeze Object.prototype (Object.freeze(Object.prototype)) in Node.js processes that parse untrusted JSON, where feasible.
- Validate and allowlist expected object shapes/keys for any JSON accepted from external agents or tools instead of trying to blocklist dangerous key names.

## Known benign look-alikes

- Ordinary class declarations using the word 'constructor' for their own constructor method (e.g. `class Foo { constructor(x) {...} }`), which do not contain the literal '.prototype.' continuation this rule requires
- Legitimate reflection/introspection code reading obj.constructor.name or obj.constructor === SomeClass for type checks, which does not continue into '.prototype.<field> ='

## References

- https://agentthreatrule.org/en/rules/ATR-2026-02105

---
Source: https://www.netzilo.com/threats/atr-prototype-pollution-via-constructor-prototype-path-bypassing
