Skip to content

Bump vm2 from 3.10.2 to 3.11.2#2160

Open
dependabot[bot] wants to merge 1 commit intomainfrom
dependabot/npm_and_yarn/vm2-3.11.2
Open

Bump vm2 from 3.10.2 to 3.11.2#2160
dependabot[bot] wants to merge 1 commit intomainfrom
dependabot/npm_and_yarn/vm2-3.11.2

Conversation

@dependabot
Copy link
Copy Markdown
Contributor

@dependabot dependabot Bot commented on behalf of github May 8, 2026

Bumps vm2 from 3.10.2 to 3.11.2.

Release notes

Sourced from vm2's releases.

v3.11.2

What's Changed

Security fixes

  • GHSA-9vg3-4rfj-wgcm — Sandbox-realm null-proto write-through via bridge.from() set trap (RCE)
  • GHSA-2cm2-m3w5-gp2f — Internal state reachable via computed-key access on globalThis
  • GHSA-9qj6-qjgg-37qq — Bridge saved-state leak via sandbox-installed Array.prototype[N] setter (RCE)

Documentation

  • docs/ATTACKS.md updated through Category 28, plus a new Defense Invariant
    ("Bridge-internal containers must not invoke sandbox code").

Full Changelog: patriksimek/vm2@v3.11.1...v3.11.2

v3.11.1

Single advisory closed plus prominent documentation of an existing escape hatch. Patch release — no API changes for valid configurations.

Embedders running untrusted code with nesting: true should read the new README section.

What's Changed

Security fix

  • GHSA-8hg8-63c5-gwmxnesting: true bypassed require: false, allowing sandbox-to-host RCE via inner NodeVM construction. The contradictory option pair { nesting: true, require: false } now throws VMError at new NodeVM(...) time citing the advisory. Same shape as the GHSA-cp6g eager FileSystem-contract probe — surface contradictory configuration at the API surface, not silently produce an unsandboxed sandbox.

Documentation

  • New README section "nesting: true is an escape hatch" under Hardening recommendations. Spells out the inner-VM independence: a nested VM's require config is chosen by the sandbox code that constructs it, not constrained by the outer VM. Do not enable nesting: true for untrusted code.
  • JSDoc on the nesting option (lib/nodevm.js) upgraded to match.
  • docs/ATTACKS.md gains Category 25 documenting the configuration trap, plus a matching row in the "How The Bridge Defends" table.

Upgrade Notes

  • If you set { nesting: true, require: false } anywhere in your codebase, new NodeVM(...) now throws. Either drop nesting: true (if you wanted deny-all), or replace require: false with an explicit require config (e.g. require: { builtin: [] }) to acknowledge that vm2 will be requireable. The error message is actionable and links to the README section.
  • No other configurations are affected. Bare new NodeVM({ nesting: true }) continues to work as documented; this is the documented escape hatch and is not closed by this patch (out of scope — would change nesting: true semantics substantially).

What This Fix Does NOT Close

nesting: true itself remains an escape hatch for any non-trivial require config. The fix closes the specific contradictory pair flagged by the advisory; the broader recommendation is in the new README section: do not enable nesting: true when running untrusted code. Constraint propagation from outer to inner NodeVM (where the outer's require config would constrain inner construction) was considered and deferred — it would change the documented semantics of nesting: true and is a major-version-shaped change.

Full Changelog: patriksimek/vm2@v3.11.0...v3.11.1

v3.11.0

Coordinated security release closing 13 advisories, plus a new bufferAllocLimit option and a realpath() method on the FileSystem adapter contract. Minor version bump because of the new public option and the FileSystem contract addition; no incompatible changes to the existing public API surface.

Embedders running untrusted code should upgrade. Several of the advisories close full sandbox-escape RCE primitives.

What's Changed

... (truncated)

Changelog

Sourced from vm2's changelog.

[3.11.2]

Three advisories closed. Patch release — no API changes.

Security fixes

  • GHSA-2cm2-m3w5-gp2f — Internal state reachable via computed property access on globalThis. The previous fix (GHSA-wp5r-2gw5-m7q7) tightened the transformer's identifier-rejection but left globalThis['VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL'] and every reflective probe of the global object (bracket access, Reflect.get, Object.getOwnPropertyDescriptor, Object.getOwnPropertyNames enumeration) returning the live state object — the transformer is a syntactic gate and cannot see through dynamic property keys. Structural fix: the bootstrap script (vm.js's setupSandboxScript source) now declares let VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL at the script's top level, which lands the binding in the context's [[GlobalLexicalEnvironment]] — reachable as a bare identifier from every script (so transformer-emitted catch handlers still resolve), but absent from globalThis's own-property table (so every computed-key probe returns undefined). The defineProperty install in setup-sandbox.js is removed entirely; the bootstrap IIFE assigns into the outer let instead. Supersedes GHSA-wp5r-2gw5-m7q7's identifier-only mitigation by closing the entire computed-key class. ATTACKS.md Category 27.
  • GHSA-9vg3-4rfj-wgcm — Sandbox breakout via null-proto throw / handleException. The post-GHSA-mpf8 hardening switched handleException and globalPromise.prototype.then onFulfilled to wrap caught/resolved values with bridge.from() for "symmetry". from() builds a sandbox-side proxy whose target the bridge treats as host-realm; calling it on a sandbox-realm null-proto value ({__proto__: null} thrown or Promise.resolve-d by sandbox JS) produced a proxy whose set trap unwrapped sandbox proxies of host references (e.g. Buffer.prototype.inspect) back to their raw host originals and stored them on the underlying sandbox object — readable via the original sandbox reference and pivot to host Function constructor → RCE. Three callsites in lib/setup-sandbox.js reverted to ensureThis() semantics; the host-Promise rejection sanitizer composes from() outside handleException so the GHSA-mpf8 invariant (host null-proto rejection values must reach sandbox callbacks bridge-wrapped) is preserved. ATTACKS.md Category 26.
  • GHSA-9qj6-qjgg-37qq — sandbox breakout via the species-defense helper neutralizeArraySpeciesBatch. The helper appended saved-state records to a fresh [] literal that — being allocated by the sandbox-side bridge closure — inherited sandbox Array.prototype. A sandbox-installed setter on Array.prototype[N] therefore captured the next saved[saved.length] = c write and exposed c.arr (a host-realm proxy) directly to attacker code, leading to host Function extraction and RCE. Fixed in lib/bridge.js by writing every saved-state entry through thisReflectDefineProperty so the appended slot is an own data property and no Array.prototype[N] setter is ever invoked while the bridge holds raw saved state. ATTACKS.md gains a new Defense Invariant ("Bridge-internal containers must not invoke sandbox code") codifying the cross-cutting principle.

[3.11.1]

Single advisory closed plus prominent documentation of an existing escape hatch. Patch release — no API changes for valid configurations.

Security fix

  • GHSA-8hg8-63c5-gwmxnesting: true bypassed require: false, allowing sandbox-to-host RCE via inner NodeVM construction. The contradictory option pair { nesting: true, require: false } now throws VMError at new NodeVM(...) time citing the advisory. Same shape as the GHSA-cp6g eager FileSystem-contract probe — surface contradictory configuration at the API surface, not silently produce an unsandboxed sandbox. ATTACKS.md Category 25.

Documentation

  • New README section "nesting: true is an escape hatch" under Hardening recommendations. Explains that nesting: true lets sandbox code require('vm2') and construct nested NodeVMs whose require config is chosen by the sandbox (not constrained by the outer config — by design of nesting). Do not enable nesting: true for untrusted code.
  • JSDoc on the nesting option (lib/nodevm.js) upgraded to spell out the escape-hatch semantics and the GHSA-8hg8 contradictory-pair rejection.
  • ATTACKS.md gains Category 25 documenting the configuration trap and a matching row in the "How The Bridge Defends" table.

Upgrade notes

  • If you set { nesting: true, require: false } anywhere in your codebase, new NodeVM(...) now throws. Either drop nesting: true (if you wanted deny-all), or replace require: false with an explicit require config (e.g. require: { builtin: [] }) to acknowledge that vm2 will be requireable. The error message is actionable and links to the README section.
  • No other configurations are affected. Bare new NodeVM({ nesting: true }) continues to work as documented; this is the documented escape hatch and is not closed by this patch (out of scope — would change nesting: true semantics substantially).

What this fix does NOT close

nesting: true itself remains an escape hatch for any non-trivial require config. The fix closes the specific contradictory pair flagged by the advisory; the broader recommendation is in the new README section: do not enable nesting: true when running untrusted code. Constraint propagation from outer to inner NodeVM (where the outer's require config would constrain inner construction) was considered and deferred — it would change the documented semantics of nesting: true and is a major-version-shaped change.

[3.11.0]

Coordinated security release closing 13 advisories, plus a new bufferAllocLimit option and a realpath() method on the FileSystem adapter contract. Minor version bump because of the new public option and the FileSystem contract addition; no incompatible changes to the existing public API surface. Embedders running untrusted code in memory-constrained environments should review the new bufferAllocLimit option and the README's Hardening recommendations section.

Upgrade notes

  • Custom fs adapters with require.root must implement realpathSync (or realpath() on a fully custom FileSystem class). Without it, new NodeVM({require: {root, fs: customAdapter}}) now throws a VMError at construction, citing GHSA-cp6g-6699-wx9c. The eager probe converts what was previously silent deny-by-default at every later require() into a single, clearly-labelled construction-time error. Default fs users are unaffected — DefaultFileSystem and VMFileSystem ship realpath() out of the box.
  • Embedders running untrusted async code should install a host-side unhandledRejection handler. The GHSA-hw58 fix closes synchronous executor throws but cannot reach async-function / async-generator / await using rejection paths (V8 creates rejection promises via the realm's intrinsic Promise). See README's Hardening recommendations and ATTACKS.md Category 22.
  • Embedders running untrusted code in memory-constrained environments should opt into a finite bufferAllocLimit (e.g. 32 * 1024 * 1024) as part of layered DoS defense. Default remains Infinity for backwards compatibility.

Security fixes

  • GHSA-grj5-jjm8-h35p — Array species self-return sandbox escape. Bridge apply and construct traps now neutralise host-array constructor and Symbol.species before every host call (and restore in a finally block). Direct write, Object.assign, non-configurable defineProperty, and prototype-level constructor variants all blocked.
  • GHSA-v37h-5mfm-c47c — Handler reconstruction via util.inspect leak. Three-layer defense: closure-scoped construction token, getHandlerObject WeakMap guard, and .constructor sentinel rebind on every handler-class prototype (including BufferHandler).
  • GHSA-qcp4-v2jj-fjx8 — Trap method on leaked handler with forged target. New handlerToTarget WeakMap pairs every handler with its canonical proxy target at construction; validateHandlerTarget(this, target) at the entry of every trap method rejects forged-this and forged-target invocations with VMError(OPNA).
  • GHSA-47x8-96vw-5wg6 — Cross-realm symbol extraction from host objects. Two-layer defense: dangerous cross-realm symbols (nodejs.util.inspect.custom, nodejs.rejection, nodejs.util.promisify.custom) are filtered at the bridge boundary; structural identity collapse pre-populates the bridge identity caches for every built-in intrinsic prototype + constructor pair so prototype walks land on sandbox primordials.
  • GHSA-55hx-c926-fr95 — Promise structural-leak / SuppressedError / AggregateError sanitisation. handleException now recurses into AggregateError.errors[] (in addition to SuppressedError.error/.suppressed); the bridge-level apply-trap recognises calls to host Promise.prototype.{then,catch,finally} by cached identity and pipes every sandbox callback through the same sanitiser.

... (truncated)

Commits

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code labels May 8, 2026
@dependabot dependabot Bot requested a review from a team as a code owner May 8, 2026 16:25
@dependabot dependabot Bot requested review from Tuseeq1 and removed request for a team May 8, 2026 16:25
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code labels May 8, 2026
@apilaskowski
Copy link
Copy Markdown
Collaborator

/gcbrun

@kolina
Copy link
Copy Markdown
Contributor

kolina commented May 9, 2026

This upgrade seems to break a bunch of our tests

Bumps [vm2](https://github.com/patriksimek/vm2) from 3.10.2 to 3.11.2.
- [Release notes](https://github.com/patriksimek/vm2/releases)
- [Changelog](https://github.com/patriksimek/vm2/blob/main/CHANGELOG.md)
- [Commits](patriksimek/vm2@v3.10.2...v3.11.2)

---
updated-dependencies:
- dependency-name: vm2
  dependency-version: 3.11.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot force-pushed the dependabot/npm_and_yarn/vm2-3.11.2 branch from 9d5f01b to 2ddd6de Compare May 9, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants