Skip to content

Prototype Pollution Report for @applitools/monitoring-commons #9

Description

@dfzysmy2tf-create

Detailed Vulnerability Type

Prototype Pollution (Configuration-Injected/Callback-Triggered · Global Prototype Tampering via Parameter Assignment), a homogenous vulnerability with dual entry points under the same core logic:

  1. TP0001: Configuration-injected prototype pollution in the main logic of timeItAsync;
  2. TP0002: Callback-triggered prototype pollution in the success callback of timeItAsync;
    Both realize precise tampering of the global Object prototype by directly assigning a native prototype object to an internal variable.

Detailed Root Cause

The makeTiming performance monitoring function of this package accepts parentPerformance as a configuration parameter, without any type validation, prototype filtering, or security validation on this parameter, and directly assigns it to the core internal performance object. When an attacker deliberately passes Object.prototype as the parentPerformance parameter, the internal performance object will directly point to the global Object prototype.
Subsequently, in the timeItAsync function, the dynamic property write operation performance[name] is executed:

  1. TP0001: The assignment is executed in the main logic of timeItAsync, directly modifying the global Object.prototype;
  2. TP0002: The assignment is executed in the success callback processing logic of timeItAsync, which is a different trigger branch of the same core vulnerability;
    Ultimately, both achieve indiscriminate global prototype pollution, and all newly created objects will inherit the injected malicious properties.

Exact Location of Vulnerable Code

TP0001 package/package/src/monitoring-commons.js Line 18 DYNAMIC_PROP_WRITE timeItAsync Main Logic
TP0002 package/package/src/monitoring-commons.js Line 31 DYNAMIC_PROP_WRITE

Reproducible POC

const lib = require('@applitools/monitoring-commons');
// Pass Object.prototype as the configuration parameter to trigger global prototype pollution
const timing = lib.makeTiming({parentPerformance: Object.prototype})
// Trigger pollution in the main logic (TP0001)/success callback (TP0002)
timing.timeItAsync('polluted').then(() => {
  // Verify that the global Object prototype is polluted
  console.log(Object.prototype.polluted); // Output the corresponding malicious value
  console.log({}.polluted); // Output the corresponding malicious value
});

General Remediation Recommendations

  1. Strict Type Validation for Input Parameters: Perform type validation on the parentPerformance parameter, only allowing the passing of native Performance objects or custom plain objects, and prohibiting the passing of native prototype objects such as Object.prototype/Function.prototype.
  2. Prototype Isolation for Input Parameters: If it is necessary to use the properties of parentPerformance, copy its properties to a newly created internal plain object through shallow/deep copy, without directly referencing the original parameter object.
  3. Privatization of Internal Objects: Define the internal performance object of the function as a private object to avoid being overwritten by externally passed parameters.
  4. Dynamic Assignment Validation: Before executing the dynamic assignment performance[name], verify whether the prototype of the performance object is the default prototype, and terminate the operation if it is tampered with.

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