Skip to content

Fix missing sandbox escape defenses (#562)#563

Open
eddieran wants to merge 1 commit intopatriksimek:mainfrom
eddieran:fix/missing-sandbox-defenses
Open

Fix missing sandbox escape defenses (#562)#563
eddieran wants to merge 1 commit intopatriksimek:mainfrom
eddieran:fix/missing-sandbox-defenses

Conversation

@eddieran
Copy link
Copy Markdown

Summary

Two critical defenses documented in docs/ATTACKS.md as present ("NOW FIXED") were absent from the actual code, leaving exploitable gaps for sandbox escapes:

  • Array Species Self-Return Defense (Category 18): V8's ArraySpeciesCreate reads constructor[Symbol.species] on raw host arrays, bypassing proxy traps entirely. If an attacker sets constructor to a species-returning function on a host array, methods like map/filter/slice store raw host values directly into that array, bypassing bridge sanitization. This adds neutralizeArraySpecies() in the apply trap (sets constructor = undefined on host arrays before/after every host call), plus constructor interception in the set and defineProperty traps.

  • Error.prepareStackTrace Safe Default (Category 19): When Error.prepareStackTrace is undefined in the sandbox, V8 falls back to Node.js's host-side prepareStackTraceCallback. If that host code throws (e.g., when error.name is a Symbol), the TypeError is a host-realm error usable for escape. This adds a defaultSandboxPrepareStackTrace function that safely handles Symbol names and exotic types, and resets to this safe default when the user sets Error.prepareStackTrace = undefined.

Changes

lib/bridge.js

  • Add SPECIES_ATTACK_SENTINEL symbol and cache Symbol.species
  • Add neutralizeArraySpecies() / neutralizeArraySpeciesArgs() -- sets constructor = undefined on host arrays via otherReflectDefineProperty
  • BaseHandler.set: intercept constructor writes to host arrays (store on proxy target)
  • BaseHandler.defineProperty: intercept constructor defineProperty on host arrays
  • BaseHandler.apply: call neutralizeArraySpeciesArgs before and after host function calls

lib/setup-sandbox.js

  • Add defaultSandboxPrepareStackTrace() -- safe stack formatter that handles Symbol names, Proxy objects, and exotic types without throwing
  • Modify prepareStackTrace setter: when user sets undefined/non-function, reset to safe default instead of storing undefined

test/vm.js

  • 6 new tests covering array species constructor interception, defineProperty interception, safe prepareStackTrace default, Symbol name handling, escape prevention, and apply-trap species neutralization

Test plan

  • All 150 tests pass (144 original + 6 new)
  • No regressions in existing security tests
  • Array species self-return attack blocked via set trap
  • Array species self-return attack blocked via defineProperty trap
  • Error.prepareStackTrace = undefined resets to safe default
  • Symbol-named errors handled without throwing host TypeError
  • Host escape via prepareStackTrace fallback prevented

Fixes #562

Two critical defenses documented as present in docs/ATTACKS.md were absent
from the actual code, leaving exploitable gaps:

1. Array Species Self-Return Defense (Category 18):
   - Add neutralizeArraySpecies() to set constructor=undefined on host arrays
     before/after every host function call in BaseHandler.apply trap
   - Intercept constructor writes to host arrays in BaseHandler.set trap
     (stores on proxy target instead of host array)
   - Intercept constructor defineProperty on host arrays in defineProperty trap
   - Add SPECIES_ATTACK_SENTINEL symbol for tamper detection

2. Error.prepareStackTrace Safe Default (Category 19):
   - Add defaultSandboxPrepareStackTrace() that safely handles Symbol names,
     Proxy objects, and exotic types without throwing
   - When user sets Error.prepareStackTrace = undefined, reset to safe default
     instead of allowing undefined (which triggers V8 fallback to host's
     prepareStackTraceCallback, enabling host-realm TypeError generation)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] Critical: Documented sandbox escape defenses absent from code (Array Species + prepareStackTrace)

1 participant