Vulnerabilities

What is Prototype Pollution?

Prototype pollution is a JavaScript vulnerability where an attacker can modify Object.prototype, injecting properties that are inherited by all objects and potentially causing security bypasses or RCE.

By the Hyrax team·5 min read·May 1, 2026
TL;DR
  1. 1.Definition
  2. 2.How Prototype Pollution Works
  3. 3.Attack Vectors
  4. 4.Impact
  5. 5.Prevention

Definition

Prototype pollution is a JavaScript vulnerability that allows an attacker to modify the properties of Object.prototype — the root prototype from which all JavaScript objects inherit. When an attacker can inject arbitrary properties into Object.prototype through unsanitized user input passed to object-merging, cloning, or path-setting functions, those properties appear on every object in the application, potentially causing security bypasses, logic manipulation, and in server-side JavaScript environments, remote code execution.

Prototype pollution became a widely-understood vulnerability class around 2018 and has been found in dozens of widely used npm packages including lodash, jQuery, and Handlebars. It is a CWE-1321 weakness.

How Prototype Pollution Works

JavaScript objects inherit from a prototype chain. Every plain object has Object.prototype at the top of its chain. If you set obj.__proto__.isAdmin = true, the isAdmin property becomes visible on all objects that do not have their own isAdmin property.

Vulnerable pattern in a deep merge function:

function merge(target, source) { for (let key in source) { target[key] = source[key]; } }

Attacker-controlled input: {"__proto__": {"isAdmin": true}}

After merging: ({}).isAdmin === true — all objects are now "admin."

Attack Vectors

JSON.parse followed by unsafe merge

User-supplied JSON is parsed and merged into an application object using a vulnerable deep-merge function. The __proto__ key in the JSON pollutes the prototype.

URL query parameters

Libraries that parse query strings like qs can interpret a[__proto__][key]=value as a prototype mutation if not configured correctly.

Path assignment functions

Functions that set values at arbitrary nested paths (lodash.set, a common pattern in form libraries and configuration systems) can be exploited if the path is user-controlled.

Impact

Security bypass

If the application checks an object property to make an authorization decision (if (obj.isAdmin)), injecting that property on the prototype bypasses the check for any object that does not explicitly set its own value.

Remote code execution in Node.js

When prototype pollution reaches certain code paths — spawning child processes, template rendering (Handlebars, Pug), or property access in native modules — it can lead to RCE. Several CVEs in popular npm packages demonstrate this path.

Prevention

Object.freeze(Object.prototype)

Freeze the prototype at application startup to prevent mutation. Simple and effective, but can break third-party libraries that legitimately add prototype methods.

Use Object.create(null) for data objects

Objects created with Object.create(null) have no prototype chain and cannot be polluted.

Sanitize merge and clone inputs

In deep-merge and deep-clone functions, block the keys __proto__, constructor, and prototype. Many popular libraries have patched their vulnerable merge implementations.

Use a schema validator

Validate untrusted input against a strict JSON schema before passing it to any merge, clone, or path-setting operation.

Prototype Pollution and Autonomous Code Governance

Hydra detects prototype pollution patterns in JavaScript and TypeScript codebases: calls to vulnerable merge/clone functions with user-controlled input, __proto__/constructor/prototype key handling in object traversal functions, and qs/querystring parsing without prototype pollution protection enabled. For lodash and similar utility library usage, Hydra verifies that versions are patched and that the usage patterns do not re-expose the vulnerability. Fixes add key filtering, upgrade vulnerable library versions, and add Object.create(null) patterns where appropriate.

Frequently Asked Questions

Does prototype pollution only affect JavaScript?

The vulnerability as described is specific to JavaScript's prototype inheritance model. Similar vulnerabilities can exist in other dynamic languages with prototype-based inheritance (some Ruby and Python patterns), but the __proto__ mechanism is JavaScript-specific. TypeScript inherits the vulnerability since it compiles to JavaScript.

Is prototype pollution a client-side or server-side vulnerability?

Both. On the client side, prototype pollution can affect frontend logic and security controls in the browser. On the server side (Node.js), it can lead to more severe outcomes including RCE when the polluted properties reach dangerous code paths. Server-side prototype pollution tends to be more impactful.

How do I know if a library I use is vulnerable to prototype pollution?

Check the CVE database and GitHub security advisories for the library. Tools like npm audit and Snyk report known prototype pollution CVEs in dependencies. For deep-merge and clone functions specifically, check whether they sanitize __proto__, constructor, and prototype keys.

Stop flagging. Start fixing.

Hyrax reviews your pull requests, remediates issues autonomously, and closes the ticket.

Join the waitlist