Safeguard
Developer Tools•

Prototype pollution defenses: what actually helps in Node.js

Prototype pollution lets attackers change shared JavaScript objects. See OWASP's defenses: Map, null prototype objects, freezing, and the limits of each.

Safeguard Security Team
4 min read

Prototype pollution lets an attacker change properties on shared JavaScript objects, which can affect every object in the application. OWASP's defenses are to use Map or Set for keyed data, create plain objects with a null prototype, and freeze built-in prototypes. Each has limits, so combine them with careful handling of untrusted keys.

What it is

OWASP describes prototype pollution as a critical vulnerability that can let attackers manipulate an application's JavaScript objects, with outcomes ranging from unauthorized data access and privilege escalation to remote code execution.

In JavaScript, objects inherit from a prototype. If code lets an attacker set a property on that shared prototype, for example through keys like __proto__ in merged or copied data, objects created later can appear to have properties that the attacker chose. Code that checks a flag on an object may then read the attacker's value.

Defense 1: use Map or Set

For keyed data that comes from users, use new Map() or new Set() instead of object literals. A Map keeps entries separate from the prototype chain, so a key named __proto__ is just a key.

Defense 2: null prototype objects

If you need a plain object, create it with Object.create(null) so it does not inherit from Object.prototype. OWASP also lists an object literal whose __proto__ key is set to null as a last resort option.

const settings = Object.create(null);
settings[userKey] = userValue;

Defense 3: freeze built-in prototypes

Object.freeze() on built-in prototypes stops new properties being added and makes existing data properties non-writable. OWASP adds two cautions. Freezing is shallow, so objects referenced by those properties stay mutable unless frozen separately. And you must test compatibility first, because libraries that modify built-in prototypes can break.

Do not rely on seal

Object.seal() blocks adding and removing properties and changing their configuration, but existing writable values can still change. OWASP says not to rely on sealing for this.

The Node.js flag

Node can run with --disable-proto=delete, which removes the __proto__ property. OWASP labels this defense in depth and notes that pollution is still possible through constructor.prototype.

node --disable-proto=delete app.js

What the OWASP page does not cover

The OWASP page does not discuss how pollution arises in merge or clone helpers, or schema validation. Those are common mitigations elsewhere, such as rejecting __proto__, constructor and prototype as keys when merging, and validating input shape. Treat that as a point to verify against your own libraries, not as OWASP guidance.

Where the risk lives in practice

Often not in your own code but in a dependency that deep merges objects, parses query strings into nested objects, or sets values by path. Keep an inventory of such libraries and update them. Reachability analysis helps here, because it shows whether the vulnerable function in a dependency is actually called by your code. Safeguard offers reachability analysis for this purpose.

Click through it at your own pace, or open it full screen.

A short checklist

  1. Replace user keyed object literals with Map where practical.
  2. Create dictionary style objects with a null prototype.
  3. Test freezing built-in prototypes in staging.
  4. Update libraries that merge or clone objects.
  5. Add a test that sends a body with a __proto__ key and confirms normal objects are unaffected.

Quick check

Does the Node flag fix prototype pollution completely?

No. OWASP calls it defense in depth, and pollution through constructor.prototype remains possible.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.