Описание
@nyariv/sandboxjs has host prototype pollution from sandbox via array intermediary (sandbox escape)
Summary
A sandbox escape vulnerability allows sandboxed code to mutate host built-in prototypes by laundering the isGlobal protection flag through array literal intermediaries. When a global prototype reference (e.g., Map.prototype, Set.prototype) is placed into an array and retrieved, the isGlobal taint is stripped, permitting direct prototype mutation from within the sandbox. This results in persistent host-side prototype pollution and may enable RCE in applications that use polluted properties in sensitive sinks (example gadget: execSync(obj.cmd)).
Details
Root Cause:
The sandbox implements a protection mechanism using the isGlobal flag in the Prop class to prevent modification of global objects and their prototypes. However, this taint tracking is lost when values pass through array/object literal creation.
Vulnerable Code Path src/executor.ts(L559-L571):
Exploitation Flow:
Protection Bypass Location src/utils.ts(L380-L385):
When the prototype is accessed via array retrieval, the isGlobal flag is no longer set, so this protection is never triggered.
PoC
Prototype pollution via array intermediary:
Observed output: false pwned
Overwrite Set.prototype.has:
Observed output: has overwritten: true
RCE via host gadget (prototype pollution -> execSync):
Observed output: uid=501(user) gid=20(staff) groups=20(staff),...
Impact
This is a sandbox escape: untrusted sandboxed code can persistently mutate host built-in prototypes (e.g., Map.prototype, Set.prototype), breaking isolation and impacting subsequent host execution. RCE is possible in applications that later use attacker-controlled (polluted) properties in sensitive sinks (e.g., passing obj.cmd to child_process.execSync).
Affected Systems: any application using @nyariv/sandboxjs to execute untrusted JavaScript.
Remediation
- Preserve
isGlobalprotection across array/object literal creation (do not unwrapPropinto raw values in a way that drops the global/prototype taint). - Add a hard block on writes to built-in prototypes (e.g.,
Map.prototype,Set.prototype, etc.) even if they are obtained indirectly through literals. - Defense-in-depth: freeze built-in prototypes in the host process before running untrusted code (may be breaking for some consumers).
Пакеты
@nyariv/sandboxjs
<= 0.8.30
0.8.31
Связанные уязвимости
SandboxJS is a JavaScript sandboxing library. Prior to 0.8.31, a sandbox escape vulnerability allows sandboxed code to mutate host built-in prototypes by laundering the isGlobal protection flag through array literal intermediaries. When a global prototype reference (e.g., Map.prototype, Set.prototype) is placed into an array and retrieved, the isGlobal taint is stripped, permitting direct prototype mutation from within the sandbox. This results in persistent host-side prototype pollution and may enable RCE in applications that use polluted properties in sensitive sinks (example gadget: execSync(obj.cmd)). This vulnerability is fixed in 0.8.31.
Уязвимость библиотеки SandboxJS, связанная с неконтролируемым изменением атрибутов прототипа объекта, позволяющая нарушителю выполнить произвольный код