Every CVE Search/ Get API key

CVE-2026-34217

SandboxJS has a Sandbox Escape via Prop Object Leak in New Handler

6.9 MediumFix available

SandboxJS is a JavaScript sandboxing library. Prior to 0.8.36, a scope modification vulnerability exists in @nyariv/sandboxjs. The vulnerability allows untrusted sandboxed code to leak internal interpreter objects through the new operator, exposing sandbox scope objects in the scope hierarchy to untrusted code; an unexpected and undesired exploit. While this could allow modifying scopes inside the sandbox, code evaluation remains sandboxed and prototypes remain protected throughout the execution. This vulnerability is fixed in 0.8.36.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
Low
Availability
None

Exploit likelihood

0.30%Up 0.2 points since Apr 7, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.9

SandboxJS has a Sandbox Escape via Prop Object Leak in New Handler

SandboxJS is a JavaScript sandboxing library. Prior to 0.8.36, a scope modification vulnerability exists in @nyariv/sandboxjs. The vulnerability allows untrusted sandboxed code to leak internal interpreter objects through the new operator, exposing sandbox scope objects in the scope hierarchy to untrusted code; an unexpected and undesired exploit. While this could allow modifying scopes inside the sandbox, code evaluation remains sandboxed and prototypes remain protected throughout the execution. This vulnerability is fixed in 0.8.36.

Record
CVE-2026-34217
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-668
Updated
2026-11-02
EUVDEUVD-2026-19301 6.9

SandboxJS is a JavaScript sandboxing library. Prior to 0.8.36, a scope modification vulnerability exists in @nyariv/sandboxjs. The vulnerability allows untrusted sandboxed code to leak internal interpreter objects through the new operator, exposing sandbox scope objects in the scope hierarchy to untrusted code; an unexpected and undesired exploit. While this could allow modifying scopes inside the sandbox, code evaluation remains sandboxed and prototypes remain protected throughout the execution. This vulnerability is fixed in 0.8.36.

Record
EUVD-2026-19301
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-hg73-4w7g-q96w 6.9

SandboxJS: Sandbox Escape via Prop Object Leak in New Handler

Description

A scope modification vulnerability exists in @nyariv/sandboxjs version 0.8.35 and below. The vulnerability allows untrusted sandboxed code to leak internal interpreter objects through the new operator, exposing sandbox scope objects in the scope hierarchy to untrusted code; an unexpected and undesired exploit. While this could allow modifying scopes inside the sandbox, code evaluation remains sandboxed and prototypes remain protected throughout the execution.

Vulnerable Code Location

Primary: The New Operator Handler

File: src/executor.ts, lines 1275–1280

addOps<new (...args: unknown[]) => unknown, unknown[]>(
  LispType.New,
  ({ done, a, b, context }) => {
    if (!context.ctx.globalsWhitelist.has(a) && !context.ctx.sandboxedFunctions.has(a)) {
      throw new SandboxAccessError(`Object construction not allowed: ${a.constructor.name}`);
    }
    done(undefined, new a(...b));  // ← b is NOT sanitized, return is NOT sanitized
  },
);

This handler has two missing sanitization steps:

  1. Arguments (b) are not passed through valueOrProp() — Constructor arguments contain raw Prop objects (internal interpreter wrappers) instead of extracted values.

  2. Return value is not passed through getGlobalProp() or sanitizeArray() — The constructed object is returned directly to the execution tree without any sanitization.

Comparison: The Call Handler (Correctly Implemented)

File: src/executor.ts, lines 493–605

addOps<unknown, Lisp[], any>(LispType.Call, ({ done, a, b, obj, context }) => {
  // ...
  const vals = b
    .map((item) => {
      if (item instanceof SpreadArray) {
        return [...item.item];
      } else {
        return [item];
      }
    })
    .flat()
    .map((item) => valueOrProp(item, context));  // ← Arguments ARE sanitized
  // ...
  let ret = evl ? evl(obj.context[obj.prop], ...vals) : (obj.context[obj.prop](...vals));
  ret = getGlobalProp(ret, context) || ret;  // ← Return IS sanitized
  sanitizeArray(ret, context);               // ← Return IS sanitized
  done(undefined, ret);
});

The Call handler correctly sanitizes both arguments (via valueOrProp) and return values (via getGlobalProp and sanitizeArray). The New handler does neither.


Why This Is Vulnerable

Step 1: What is a Prop Object?

The sandbox interpreter wraps every value access in a Prop object (defined at src/utils.ts, lines 565–582). A Prop has:

class Prop {
  context: any;       // The object the property belongs to
  prop: PropertyKey;  // The property name
  isConst: boolean;
  isGlobal: boolean;
  isVariable: boolean;
}

When sandboxed code accesses a variable like isNaN, the interpreter creates Prop(scope.allVars, 'isNaN'). The context field is a direct reference to the scope's variable storage object.

Step 2: What is in scope.allVars?

At the global scope level, scope.allVars is the same object as options.globals — the SAFE_GLOBALS object containing:

{
  globalThis: <real globalThis>,
  Function: <real Function constructor>,
  eval: <real eval function>,
  console: { log: console.log, ... },
  Array, Object, Map, Set, Promise, Date, Error, RegExp,
  isNaN, parseInt, parseFloat, ...
}

These are the real host JavaScript objects. The sandbox normally protects them by intercepting reads through the Prop handler and replacing dangerous ones via the evals Map.

Step 3: How the Prop Leaks Through new

When sandboxed code executes new Constructor(someVariable):

  1. The interpreter evaluates someVariable — this produces a Prop object: Prop(scope.allVars, 'someVariable')
  2. The New handler receives this Prop as-is in the b array (no valueOrProp() call)
  3. new Constructor(...[Prop]) passes the raw Prop object to the constructor function
  4. Inside the constructor, the Prop is received as a named parameter 5.…
Record
GHSA-hg73-4w7g-q96w
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-668
Updated
2026-11-02
NVD 6.9

SandboxJS is a JavaScript sandboxing library. Prior to 0.8.36, a scope modification vulnerability exists in @nyariv/sandboxjs. The vulnerability allows untrusted sandboxed code to leak internal interpreter objects through the new operator, exposing sandbox scope objects in the scope hierarchy to untrusted code; an unexpected and undesired exploit. While this could allow modifying scopes inside the sandbox, code evaluation remains sandboxed and prototypes remain protected throughout the execution. This vulnerability is fixed in 0.8.36.

Record
CVE-2026-34217
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
CVSS 3.1
7.2 HighCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Weakness
CWE-668
Updated
2026-11-02
OSVGHSA-hg73-4w7g-q96w 6.9

SandboxJS: Sandbox Escape via Prop Object Leak in New Handler

Description

A scope modification vulnerability exists in @nyariv/sandboxjs version 0.8.35 and below. The vulnerability allows untrusted sandboxed code to leak internal interpreter objects through the new operator, exposing sandbox scope objects in the scope hierarchy to untrusted code; an unexpected and undesired exploit. While this could allow modifying scopes inside the sandbox, code evaluation remains sandboxed and prototypes remain protected throughout the execution.

Vulnerable Code Location

Primary: The New Operator Handler

File: src/executor.ts, lines 1275–1280

addOps<new (...args: unknown[]) => unknown, unknown[]>(
  LispType.New,
  ({ done, a, b, context }) => {
    if (!context.ctx.globalsWhitelist.has(a) && !context.ctx.sandboxedFunctions.has(a)) {
      throw new SandboxAccessError(`Object construction not allowed: ${a.constructor.name}`);
    }
    done(undefined, new a(...b));  // ← b is NOT sanitized, return is NOT sanitized
  },
);

This handler has two missing sanitization steps:

  1. Arguments (b) are not passed through valueOrProp() — Constructor arguments contain raw Prop objects (internal interpreter wrappers) instead of extracted values.

  2. Return value is not passed through getGlobalProp() or sanitizeArray() — The constructed object is returned directly to the execution tree without any sanitization.

Comparison: The Call Handler (Correctly Implemented)

File: src/executor.ts, lines 493–605

addOps<unknown, Lisp[], any>(LispType.Call, ({ done, a, b, obj, context }) => {
  // ...
  const vals = b
    .map((item) => {
      if (item instanceof SpreadArray) {
        return [...item.item];
      } else {
        return [item];
      }
    })
    .flat()
    .map((item) => valueOrProp(item, context));  // ← Arguments ARE sanitized
  // ...
  let ret = evl ? evl(obj.context[obj.prop], ...vals) : (obj.context[obj.prop](...vals));
  ret = getGlobalProp(ret, context) || ret;  // ← Return IS sanitized
  sanitizeArray(ret, context);               // ← Return IS sanitized
  done(undefined, ret);
});

The Call handler correctly sanitizes both arguments (via valueOrProp) and return values (via getGlobalProp and sanitizeArray). The New handler does neither.


Why This Is Vulnerable

Step 1: What is a Prop Object?

The sandbox interpreter wraps every value access in a Prop object (defined at src/utils.ts, lines 565–582). A Prop has:

class Prop {
  context: any;       // The object the property belongs to
  prop: PropertyKey;  // The property name
  isConst: boolean;
  isGlobal: boolean;
  isVariable: boolean;
}

When sandboxed code accesses a variable like isNaN, the interpreter creates Prop(scope.allVars, 'isNaN'). The context field is a direct reference to the scope's variable storage object.

Step 2: What is in scope.allVars?

At the global scope level, scope.allVars is the same object as options.globals — the SAFE_GLOBALS object containing:

{
  globalThis: <real globalThis>,
  Function: <real Function constructor>,
  eval: <real eval function>,
  console: { log: console.log, ... },
  Array, Object, Map, Set, Promise, Date, Error, RegExp,
  isNaN, parseInt, parseFloat, ...
}

These are the real host JavaScript objects. The sandbox normally protects them by intercepting reads through the Prop handler and replacing dangerous ones via the evals Map.

Step 3: How the Prop Leaks Through new

When sandboxed code executes new Constructor(someVariable):

  1. The interpreter evaluates someVariable — this produces a Prop object: Prop(scope.allVars, 'someVariable')
  2. The New handler receives this Prop as-is in the b array (no valueOrProp() call)
  3. new Constructor(...[Prop]) passes the raw Prop object to the constructor function
  4. Inside the constructor, the Prop is received as a named parameter 5.…
Record
GHSA-hg73-4w7g-q96w
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-668
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@nyariv/sandboxjs
npm
through 0.8.35
0.8.36
@nyariv/sandboxjs
npm
before 0.8.36
0.8.36

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-34217 is a medium vulnerability (CVSS 6.9) in Nyariv Sandboxjs, published April 3, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.30%, the 23rd percentile. Fixed in @nyariv/sandboxjs 0.8.36.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open