
Node.js sandbox for running untrusted JavaScript in-process, using Proxies and controlled require to restrict built-in and external module access.
vm2 is a sandbox that can run untrusted code with whitelisted Node's built-in modules.
For an in-depth look at vm2’s internals, see the CONTRIBUTING.md file.
Try it yourself:
import { runInNewContext } from "node:vm";
runInNewContext('this.constructor.constructor("return process")().exit()');
console.log('Never gets executed.');
import { VM } from 'vm2';
new VM().run('this.constructor.constructor("return process")().exit()');
// Throws ReferenceError: process is not defined
npm install vm2
import { VM } from 'vm2';
const vm = new VM();
vm.run(`process.exit()`); // TypeError: process.exit is not a function
import { NodeVM } from 'vm2';
const vm = new NodeVM({
require: {
external: true,
root: './',
},
});
vm.run(
`
var request = require('request');
request('http://www.google.com', function (error, response, body) {
console.error(error);
if (!error && response.statusCode == 200) {
console.log(body); // Show the HTML for the Google homepage.
}
});
`,
'vm.js',
);
VM is a simple sandbox to synchronously run untrusted code without the require feature. Only JavaScript built-in objects and Node's Buffer are available. Scheduling functions (setInterval, setTimeout and setImmediate) are not available by default.
Options:
timeout - Script timeout in milliseconds. WARNING: You might want to use this option together with allowAsync=false. Further, operating on returned objects from the sandbox can run arbitrary code and circumvent the timeout. One should test if the returned object is a primitive with typeof and fully discard it (doing logging or creating error messages with such an object might also run arbitrary code again) in the other case.sandbox - VM's global object.compiler - javascript (default), typescript, coffeescript or custom compiler function. The library expects you to have compiler pre-installed if the value is set to typescript or coffeescript.eval - If set to false any calls to eval or function constructors (Function, GeneratorFunction, etc.) will throw an EvalError (default: true).wasm - If set to false any attempt to compile a WebAssembly module will throw a WebAssembly.CompileError (default: true).allowAsync - If set to false any attempt to run code using async will throw a VMError (default: true).IMPORTANT: Timeout is only effective on synchronous code that you run through run. Timeout does NOT work on any method returned by VM. There are some situations when timeout doesn't work - see #244.
import { VM } from 'vm2';
const vm = new VM({
timeout: 1000,
allowAsync: false,
sandbox: {},
});
vm.run('process.exit()'); // throws ReferenceError: process is not defined
You can also retrieve values from VM.
let number = vm.run('1337'); // returns 1337
TIP: See tests for more usage examples.
Unlike VM, NodeVM allows you to require modules in the same way that you would in the regular Node's context.
Options: