Listen to this Post
The vulnerability arises because `executorUtils.ts` builds host JavaScript functions via `createFunction()` that are indistinguishable from normal functions. A sandboxed script can capture `Function.caller` inside such a function, leaking the internal `LispType.Call` runtime callback from call.ts. This callback normally handles Lisp operations but lacks authentication on its `params` object. By invoking the leaked callback with a forged `params` object, an attacker controls fields like obj.context, obj.prop, obj.get, and context.evals.get. In `call.ts` lines 47, 70, and 149, these fields are used without validation. The attacker can then craft a fake `obj` and `context` to call internal primitives, extract blocked host statics (e.g., Object.defineProperty), recover the real host `Function` constructor, and finally execute arbitrary JavaScript. The provided Proof of Concept demonstrates leaking the callback via (function fn(){ return fn.caller; })(), then using `callOp` with controlled `obj` and `context` to retrieve `Function` and run process.getBuiltinModule("child_process").execSync("whoami").toString(), escaping the sandbox completely.
DailyCVE Form:
Platform: Node.js sandbox
Version: Not specified
Vulnerability: Function.caller leak
Severity: Critical
date: Unknown
Prediction: No patch yet
What Undercode Say:
Install vulnerable package
npm install @nyariv/sandboxjs@<unknown>
Test sandbox escape
node -e "const sandb = require('@nyariv/sandboxjs').default; const sand = new sandb(); const payload = `const callOp = (function fn() { return fn.caller; })(); ...`; console.log(sand.compile(payload)().run());"
// Minimal PoC to leak callback
const sandb = require('@nyariv/sandboxjs').default;
const sand = new sandb();
const leakCode = <code>(function fn() { return fn.caller; })()</code>;
const callOp = sand.compile(leakCode)().run();
console.log(callOp); // internal LispType.Call
Exploit:
Attacker defines a sandbox function, reads its `caller` to obtain the internal `LispType.Call` callback. Then invokes that callback with a crafted `params` object having `obj.context` set to a fake host context and `obj.prop` targeting 'defineProperty'. The callback returns blocked host statics, which are used to reconstruct the real `Function` constructor. Finally, the attacker calls `Function` with a string containing process.getBuiltinModule('child_process').execSync('whoami'), achieving RCE.
Protection from this CVE:
- Upgrade to a patched version if available (none indicated as of now).
- Avoid using `@nyariv/sandboxjs` for untrusted code.
- Apply runtime hardening: disable `Function.caller` via strict mode or
--disallow-code-generation-from-strings. - Use alternative sandboxing libraries (e.g., `vm2` with patches,
isolated-vm). - Monitor for official patch and apply immediately upon release.
Impact:
Complete sandbox escape leading to remote code execution (RCE). An attacker can execute arbitrary operating system commands, read/write files, compromise the host system, and pivot to internal networks. The confidentiality, integrity, and availability of the host are fully lost.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

