Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

vm2

Package Overview
Dependencies
Maintainers
1
Versions
65
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.2.0 to 3.3.0

.vscode/launch.json

4

CHANGELOG.md

@@ -0,1 +1,5 @@

v3.2.0 (2017-02-10)
-------------------
[new] Added support for pre-compiled scripts (VMScript)
v3.1.0 (2016-09-03)

@@ -2,0 +6,0 @@ -------------------

6

lib/cli.js

@@ -7,6 +7,6 @@ const fs = require('fs');

if (process.argv[2]) {
let path = pa.resolve(process.argv[2]);
const path = pa.resolve(process.argv[2]);
console.log(`\x1B[90m[vm] creating VM for ${path}\x1B[39m`);
let started = Date.now();
const started = Date.now();

@@ -26,3 +26,3 @@ try {

} else {
let {stack} = ex;
const {stack} = ex;

@@ -29,0 +29,0 @@ if (stack) {

@@ -49,3 +49,3 @@ 'use strict'

let arr = new host.Array();
const arr = new host.Array();
for (let i = 0, l = args.length; i < l; i++) arr[i] = Decontextify.value(args[i]);

@@ -74,3 +74,3 @@ return arr;

function: function(fnc, traps, deepTraps, mock) {
let self = Decontextify.object(fnc, host.Object.assign({
const self = Decontextify.object(fnc, host.Object.assign({
apply: (target, context, args) => {

@@ -114,3 +114,3 @@ try {

object: function(object, traps, deepTraps, mock) {
let proxy = new host.Proxy(object, host.Object.assign({
const proxy = new host.Proxy(object, host.Object.assign({
get: (target, key, receiver) => {

@@ -253,3 +253,3 @@ if (key === 'vmProxyTarget' && DEBUG) return object;

let arr = new Array();
const arr = new Array();
for (let i = 0, l = args.length; i < l; i++) arr[i] = Contextify.value(args[i]);

@@ -278,3 +278,3 @@ return arr;

function: function(fnc, traps, deepTraps, mock) {
let self = Contextify.object(fnc, host.Object.assign({
const self = Contextify.object(fnc, host.Object.assign({
apply: (target, context, args) => {

@@ -318,3 +318,3 @@ try {

object: function(object, traps, deepTraps, mock) {
let proxy = new host.Proxy(object, host.Object.assign({
const proxy = new host.Proxy(object, host.Object.assign({
get: (target, key, receiver) => {

@@ -321,0 +321,0 @@ if (key === 'vmProxyTarget' && DEBUG) return object;

@@ -9,3 +9,3 @@ const fs = require('fs');

const _compileToJS = function(code, compiler) {
const _compileToJS = function compileToJS(code, compiler) {
if ('function' === typeof compiler) return compiler(code);

@@ -31,7 +31,32 @@

const _freeze = function freeze(object) {
if (typeof object === 'object' || object === 'function') {
object = new Proxy(object, {
set: (target, key) => { throw new Error('Object is read-only.') },
setPrototypeOf: (target, key) => { throw new Error('Object is read-only.') },
defineProperty: (target, key) => { throw new Error('Object is read-only.') },
deleteProperty: (target, key) => { throw new Error('Object is read-only.') },
isExtensible: (target, key) => false,
preventExtensions: (target) => { throw new Error('Object is read-only.') }
});
}
return object;
}
/**
* Class Script
*
* @class
*/
class VMScript {
/**
* Create VMScript instance.
*
* @param {String} code Code to run.
* @param {String} [filename] Filename that shows up in any stack traces produced from this script.
* @return {VMScript}
*/
constructor(code, filename) {

@@ -41,2 +66,8 @@ this.code = code;

}
/**
* Wraps the code.
*
* @return {VMScript}
*/

@@ -49,2 +80,8 @@ wrap(prefix, postfix) {

}
/**
* Compiles the code. If called multiple times, the code is only compiled once.
*
* @return {VMScript}
*/

@@ -71,2 +108,14 @@ compile() {

/**
* Makes the value read only.
*
* @static
* @param {*} value Value to freeze.
* @return {*} Frozen value.
*/
static freeze(object) {
return _freeze(object);
}
/**
* Create VM instance.

@@ -88,3 +137,3 @@ *

let host = {
const host = {
console,

@@ -148,3 +197,3 @@ String,

let script = code instanceof VMScript ? code : new VMScript(code);
const script = code instanceof VMScript ? code : new VMScript(code);

@@ -165,3 +214,5 @@ try {

* Class NodeVM.
*
*
* @class
* @extends {EventEmitter}
* @property {Object} module Pointer to main module.

@@ -172,2 +223,14 @@ */

/**
* Makes the value read only.
*
* @static
* @param {*} value Value to freeze.
* @return {*} Frozen value.
*/
static freeze(object) {
return _freeze(object);
}
/**
* Create NodeVM instance.

@@ -195,3 +258,3 @@ *

let host = {
const host = {
require,

@@ -244,3 +307,3 @@ process,

let closure = vm.runInContext(`(function (vm, host, Contextify, Decontextify, Buffer) { ${sb} \n})`, this._context, {
const closure = vm.runInContext(`(function (vm, host, Contextify, Decontextify, Buffer) { ${sb} \n})`, this._context, {
filename: `${__dirname}/sandbox.js`,

@@ -292,2 +355,3 @@ displayErrors: false

*
* @param {String} module Module name.
* @return {*} Exported module.

@@ -324,11 +388,11 @@ */

let module = vm.runInContext("({exports: {}})", this._context, {
const module = vm.runInContext("({exports: {}})", this._context, {
displayErrors: false
});
let script = code instanceof VMScript ? code : new VMScript(code, filename);
const script = code instanceof VMScript ? code : new VMScript(code, filename);
script.wrap('(function (exports, require, module, __filename, __dirname) { ', ' \n})');
try {
let closure = script.compile()._compiled.runInContext(this._context, {
const closure = script.compile()._compiled.runInContext(this._context, {
filename: script.filename,

@@ -404,4 +468,2 @@ displayErrors: false

*
* @param {String} message Error message.
*
* @class

@@ -414,2 +476,9 @@ * @extends {Error}

class VMError extends Error {
/**
* Create VMError instance.
*
* @param {String} message Error message.
* @return {VMError}
*/
constructor(message) {

@@ -416,0 +485,0 @@ super(message);

@@ -53,3 +53,3 @@ const {Script} = host.require('vm');

// Precompile script
let script = new Script(code, {
const script = new Script(code, {
filename: filename || "vm.js",

@@ -80,4 +80,4 @@ displayErrors: false

let exists = fs.existsSync(path);
let isdir = exists ? fs.statSync(path).isDirectory() : false;
const exists = fs.existsSync(path);
const isdir = exists ? fs.statSync(path).isDirectory() : false;

@@ -132,3 +132,3 @@ // direct file match

try {
let script = new Script(`(function (exports, require, module, process) { 'use strict'; ${BUILTIN_MODULES[modulename]} \n});`, {
const script = new Script(`(function (exports, require, module, process) { 'use strict'; ${BUILTIN_MODULES[modulename]} \n});`, {
filename: `${modulename}.vm.js`

@@ -138,3 +138,3 @@ });

// setup module scope
let module = BUILTINS[modulename] = {
const module = BUILTINS[modulename] = {
exports: {},

@@ -214,3 +214,3 @@ require: _requireBuiltin

let paths = current_dirname.split(pa.sep);
const paths = current_dirname.split(pa.sep);

@@ -234,7 +234,7 @@ while (paths.length) {

let dirname = pa.dirname(filename);
let extname = pa.extname(filename);
const dirname = pa.dirname(filename);
const extname = pa.extname(filename);
if (vm.options.require.root) {
let requiredPath = pa.resolve(vm.options.require.root);
const requiredPath = pa.resolve(vm.options.require.root);
if (dirname.indexOf(requiredPath) !== 0) {

@@ -245,3 +245,3 @@ throw new VMError(`Module '${modulename}' is not allowed to be required. The path is outside the border!`, "EDENIED");

let module = CACHE[filename] = {
const module = CACHE[filename] = {
filename,

@@ -270,7 +270,7 @@ exports: {},

global.setTimeout = function(callback, delay, ...args) {
let tmr = host.setTimeout(function() {
const tmr = host.setTimeout(function() {
callback.apply(null, args)
}, delay);
let local = {
const local = {
ref() { return tmr.ref(); },

@@ -285,7 +285,7 @@ unref() { return tmr.unref(); }

global.setInterval = function(callback, interval, ...args) {
let tmr = host.setInterval(function() {
const tmr = host.setInterval(function() {
callback.apply(null, args)
}, interval);
let local = {
const local = {
ref() { return tmr.ref(); },

@@ -300,7 +300,7 @@ unref() { return tmr.unref(); }

global.setImmediate = function(callback, ...args) {
let tmr = host.setImmediate(function() {
const tmr = host.setImmediate(function() {
callback.apply(null, args)
});
let local = {
const local = {
ref() { return tmr.ref(); },

@@ -307,0 +307,0 @@ unref() { return tmr.unref(); }

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

],
"version": "3.2.0",
"version": "3.3.0",
"main": "index.js",

@@ -19,0 +19,0 @@ "repository": {

@@ -23,2 +23,17 @@ # vm2 [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Package Quality][quality-image]][quality-url] [![Travis CI][travis-image]][travis-url]

**What is the difference between Node's vm and vm2?**
Try it yourself:
```javascript
const vm = require('vm');
vm.runInNewContext('this.constructor.constructor("return process")().exit()');
console.log('Never gets executed.');
```
```javascript
const {VM} = require('vm2');
new VM().run('this.constructor.constructor("return process")().exit()');
```
## Installation

@@ -63,2 +78,4 @@

* [VMScript](#vmscript)
* [Error handling](#error-handling)
* [Read-only objects](#read-only-objects)
* [Cross-sandbox relationships](#cross-sandbox-relationships)

@@ -219,2 +236,31 @@ * [CLI](#cli)

## Read-only objects
To prevent sandboxed script to add/change/delete properties to/from the proxied objects, you can use `VM.freeze`/`NodeVM.freeze` methods to make the object read-only. Rather than freezing the object itself (like builtin `Object.freeze` method does) it creates a new proxy so the original object remains untouched.
**Example without using `VM.freeze`:**
```javascript
const util = {
add: (a, b) => a + b
}
const vm = new VM({
sandbox: {util}
});
vm.run('util.add = (a, b) => a - b');
console.log(util.add(1, 1)); // returns 0
```
**Example with using `VM.freeze`:**
```javascript
const vm = new VM({
sandbox: {util: VM.freeze(util)}
});
vm.run('util.add = (a, b) => a - b'); // throws Object is read-only.
```
## Cross-sandbox relationships

@@ -226,3 +272,3 @@

let sandbox = {
const sandbox = {
object: new Object(),

@@ -233,3 +279,3 @@ func: new Function(),

let vm = new VM({sandbox});
const vm = new VM({sandbox});

@@ -236,0 +282,0 @@ assert.ok(vm.run(`object`) === sandbox.object);

@@ -739,1 +739,51 @@ const assert = require("assert");

})
describe('read-only contextified items', () => {
it('without read-only', done => {
let x = {
a() {
return 'a';
},
b() {
return 'b'
}
}
let vm = new VM({
sandbox: {x}
});
vm.run('x.a = () => { return `-` }; (y) => { y.b = () => { return `--` } }')(x);
assert.strictEqual(x.a(), '-');
assert.strictEqual(x.b(), '--');
done()
})
it('with read-only', done => {
let x = VM.freeze({
a() {
return 'a';
},
b() {
return 'b'
}
});
let vm = new VM({
sandbox: {x}
});
assert.throws(() => {
vm.run('x.a = () => { return `-` };');
}, /Object is read-only\./);
assert.throws(() => {
vm.run('(y) => { y.b = () => { return `--` } }')(x);
}, /Object is read-only\./);
done()
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc