🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

vm2

Package Overview
Dependencies
Maintainers
1
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vm2 - npm Package Compare versions

Comparing version
3.11.0
to
3.11.1
+31
-2
lib/nodevm.js

@@ -233,4 +233,11 @@ 'use strict';

* @param {boolean} [options.nesting=false] -
* <b>WARNING: Allowing this is a security risk as scripts can create a NodeVM which can require any host module.</b>
* Allow nesting of VMs.
* <b>WARNING: <code>nesting: true</code> is an escape hatch — sandbox code
* can <code>require('vm2')</code> and construct nested NodeVMs whose
* <code>require</code> config is chosen by the sandbox, NOT constrained by
* the outer config. Enabling <code>nesting: true</code> grants the sandbox
* unrestricted host module access. Do not enable for untrusted code.
* See README "`nesting: true` is an escape hatch".</b>
* Combining <code>nesting: true</code> with <code>require: false</code>
* throws <code>VMError</code> at construction (GHSA-8hg8-63c5-gwmx) — the
* pair is contradictory.
* @param {("commonjs"|"none")} [options.wrapper="commonjs"] - <code>commonjs</code> to wrap script into CommonJS wrapper,

@@ -247,2 +254,24 @@ * <code>none</code> to retrieve value returned by the script.

constructor(options = {}) {
// SECURITY (GHSA-8hg8-63c5-gwmx): `nesting: true` injects a NESTING_OVERRIDE
// builtin that exposes `vm2` to the sandbox regardless of `require: false`.
// The sandbox then constructs an inner NodeVM with attacker-chosen `require`
// config (unconstrained by the outer config — by design of nesting) and
// reaches `child_process` for full host RCE. The contradictory option pair
// is the specific trap the advisory describes; reject it at construction
// with a clear error rather than silently producing an unsandboxed config.
// (Bare `nesting: true` without `require: false` continues to work as the
// documented escape hatch; the README "`nesting: true` is an escape hatch"
// section explains the broader trade-off.)
if (options.nesting === true && options.require === false) {
throw new VMError(
'NodeVM `nesting: true` is incompatible with `require: false`. '
+ '`nesting: true` is an escape hatch that lets sandbox code '
+ '`require(\'vm2\')` and construct nested VMs unconstrained by the outer '
+ 'config — which contradicts `require: false`. To deny all requires, '
+ 'remove `nesting: true`. To allow nested VMs, replace `require: false` '
+ 'with an explicit config (e.g. `require: { builtin: [] }`) so the '
+ 'tradeoff is visible. See README "`nesting: true` is an escape hatch". '
+ 'Context: GHSA-8hg8-63c5-gwmx.'
);
}
const {

@@ -249,0 +278,0 @@ compiler,

+1
-1

@@ -16,3 +16,3 @@ {

],
"version": "3.11.0",
"version": "3.11.1",
"main": "index.js",

@@ -19,0 +19,0 @@ "sideEffects": false,

@@ -505,2 +505,20 @@ # vm2 [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![License][license-image]][license-url] [![Node.js CI](https://github.com/patriksimek/vm2/actions/workflows/test.yml/badge.svg)](https://github.com/patriksimek/vm2/actions/workflows/test.yml) [![Known Vulnerabilities][snyk-image]][snyk-url]

### 5. `nesting: true` is an escape hatch
`nesting: true` lets sandbox code `require('vm2')` and construct nested NodeVMs. **The nested VM's `require` config is chosen by the sandbox code that constructs it, not constrained by the outer VM.** Concretely:
```js
const vm = new NodeVM({ nesting: true, require: { builtin: [] } });
vm.run(`
const { NodeVM: NVM } = require('vm2');
// Inner VM's config is whatever the sandbox writes here:
const inner = new NVM({ require: { builtin: ['child_process'] } });
inner.run('require("child_process").execSync("id")'); // RCE
`);
```
If you set `nesting: true`, you have effectively granted the sandbox the same trust level you have. **Do not enable `nesting: true` for untrusted code.** Use it only when you trust the sandboxed code itself but want VM-style execution semantics (fresh global, controlled timeouts) for non-security reasons.
The combination `{ nesting: true, require: false }` throws `VMError` at construction (GHSA-8hg8-63c5-gwmx) because the pair is contradictory: `nesting: true` makes `vm2` requireable regardless of `require: false`, so the deny-all expectation cannot be honored. To deny all requires, remove `nesting: true`. To allow nested VMs, replace `require: false` with an explicit config so the tradeoff is visible.
## Known Issues

@@ -507,0 +525,0 @@