Comparing version 3.4.6 to 3.5.0
@@ -0,1 +1,8 @@ | ||
v3.5.0 (2017-08-31) | ||
------------------- | ||
[new] Allow a custom compiler to recieve the filetype (Orta Therox) | ||
[new] Allow in-sandbox requires to also get called through the compiler (Orta Therox) | ||
[new] Support whitelisting modules inside a VM (Orta Therox) | ||
[new] Add TypeScript definition (Orta Therox) | ||
v3.4.0 (2017-03-28) | ||
@@ -11,3 +18,3 @@ ------------------- | ||
------------------- | ||
[new] Added support for pre-compiled scripts (VMScript) | ||
[new] Added support for pre-compiled scripts via VMScript | ||
@@ -14,0 +21,0 @@ v3.1.0 (2016-09-03) |
@@ -11,4 +11,4 @@ const fs = require('fs'); | ||
const _compileToJS = function compileToJS(code, compiler) { | ||
if ('function' === typeof compiler) return compiler(code); | ||
const _compileToJS = function compileToJS(code, compiler, filename) { | ||
if ('function' === typeof compiler) return compiler(code, filename); | ||
@@ -20,3 +20,7 @@ switch (compiler) { | ||
case 'text/coffeescript': | ||
return require('coffee-script').compile(code, {header: false, bare: true}); | ||
try { | ||
return require('coffee-script').compile(code, {header: false, bare: true}); | ||
} catch (ex) { | ||
throw VMError('Coffee-Script compiler is not installed.'); | ||
} | ||
@@ -397,3 +401,3 @@ case 'javascript': | ||
if (this.options.compiler !== 'javascript') { | ||
code = _compileToJS(code, this.options.compiler); | ||
code = _compileToJS(code, this.options.compiler, filename); | ||
} | ||
@@ -400,0 +404,0 @@ |
@@ -50,4 +50,9 @@ const {Script} = host.require('vm'); | ||
// Load module | ||
var code = `(function (exports, require, module, __filename, __dirname) { 'use strict'; ${fs.readFileSync(filename, "utf8")} \n});`; | ||
var contents = fs.readFileSync(filename, "utf8") | ||
if (typeof vm.options.compiler === "function") { | ||
contents = vm.options.compiler(contents, filename) | ||
} | ||
var code = `(function (exports, require, module, __filename, __dirname) { 'use strict'; ${contents} \n});`; | ||
// Precompile script | ||
@@ -211,2 +216,7 @@ const script = new Script(code, { | ||
if(Array.isArray(vm.options.require.external)) { | ||
const isWhitelisted = vm.options.require.external.indexOf(modulename) !== -1 | ||
if (!isWhitelisted) throw new VMError(`The module '${modulename}' is not whitelisted in VM.`, "EDENIED"); | ||
} | ||
const paths = current_dirname.split(pa.sep); | ||
@@ -213,0 +223,0 @@ |
@@ -16,3 +16,3 @@ { | ||
], | ||
"version": "3.4.6", | ||
"version": "3.5.0", | ||
"main": "index.js", | ||
@@ -36,3 +36,4 @@ "repository": { | ||
"vm2": "./bin/vm2" | ||
} | ||
}, | ||
"types": "index.d.ts" | ||
} |
@@ -56,15 +56,15 @@ # 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] | ||
const vm = new NodeVM({ | ||
require: { | ||
external: true | ||
} | ||
require: { | ||
external: true | ||
} | ||
}); | ||
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. | ||
} | ||
}) | ||
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'); | ||
@@ -89,3 +89,3 @@ ``` | ||
VM is a simple sandbox, without `require` feature, to synchronously run an untrusted code. Only JavaScript built-in objects + Buffer are available. | ||
VM is a simple sandbox, without `require` feature, to synchronously run an untrusted code. Only JavaScript built-in objects + Buffer are available. Scheduling functions (`setInterval`, `setTimeout` and `setImmediate`) are not available by default. | ||
@@ -96,3 +96,3 @@ **Options:** | ||
* `sandbox` - VM's global object. | ||
* `compiler` - `javascript` (default) or `coffeescript` or custom compiler function. | ||
* `compiler` - `javascript` (default) or `coffeescript` or custom compiler function. The library expects you to have coffee-script pre-installed if the compiler is set to `coffeescript`. | ||
@@ -128,6 +128,6 @@ **IMPORTANT**: Timeout is only effective on code you run through `run`. Timeout is NOT effective on any method returned by VM. | ||
* `sandbox` - VM's global object. | ||
* `compiler` - `javascript` (default) or `coffeescript` or custom compiler function. | ||
* `compiler` - `javascript` (default) or `coffeescript` or custom compiler function (which receives the code, and it's filepath). The library expects you to have coffee-script pre-installed if the compiler is set to `coffeescript`. | ||
* `require` - `true` or object to enable `require` method (default: `false`). | ||
* `require.external` - `true` to enable `require` of external modules (default: `false`). | ||
* `require.builtin` - Array of allowed builtin modules (default: none). | ||
* `require.external` - `true` or an array of allowed external modules (default: `false`). | ||
* `require.builtin` - Array of allowed builtin modules, accepts ["*"] for all (default: none). | ||
* `require.root` - Restricted path where local modules can be required (default: every path). | ||
@@ -148,3 +148,3 @@ * `require.mock` - Collection of mock modules (both external or builtin). | ||
const vm = new NodeVM({ | ||
console: 'inherit', | ||
console: 'inherit', | ||
sandbox: {}, | ||
@@ -156,5 +156,5 @@ require: { | ||
mock: { | ||
fs: { | ||
readFileSync() { return 'Nice try!'; } | ||
} | ||
fs: { | ||
readFileSync() { return 'Nice try!'; } | ||
} | ||
} | ||
@@ -173,3 +173,3 @@ } | ||
functionWithCallbackInSandbox('world', (greeting) => { | ||
console.log(greeting); | ||
console.log(greeting); | ||
}); | ||
@@ -226,15 +226,15 @@ ``` | ||
try { | ||
var script = new VMScript("Math.random()").compile(); | ||
var script = new VMScript("Math.random()").compile(); | ||
} catch (err) { | ||
console.error('Failed to compile script.', err); | ||
console.error('Failed to compile script.', err); | ||
} | ||
try { | ||
vm.run(script); | ||
vm.run(script); | ||
} catch (err) { | ||
console.error('Failed to execute script.', err); | ||
console.error('Failed to execute script.', err); | ||
} | ||
process.on('uncaughtException', (err) => { | ||
console.error('Asynchronous error caught.', err); | ||
console.error('Asynchronous error caught.', err); | ||
}) | ||
@@ -251,7 +251,7 @@ ``` | ||
const util = { | ||
add: (a, b) => a + b | ||
add: (a, b) => a + b | ||
} | ||
const vm = new VM({ | ||
sandbox: {util} | ||
sandbox: {util} | ||
}); | ||
@@ -288,5 +288,5 @@ | ||
const sandbox = { | ||
object: new Object(), | ||
func: new Function(), | ||
buffer: new Buffer([0x01, 0x05]) | ||
object: new Object(), | ||
func: new Function(), | ||
buffer: new Buffer([0x01, 0x05]) | ||
} | ||
@@ -293,0 +293,0 @@ |
@@ -466,2 +466,27 @@ const assert = require("assert"); | ||
it('optionally can run a custom compiler function', () => { | ||
var ranCustomCompiler = false | ||
const scriptCode = 'var a = 1;' | ||
let vm = new NodeVM({ | ||
compiler: (code) => { | ||
ranCustomCompiler = true | ||
assert.equal(code, scriptCode) | ||
} | ||
}) | ||
vm.run(scriptCode) | ||
assert.equal(ranCustomCompiler, true); | ||
}) | ||
it('optionally passes a filename to a custom compiler function', () => { | ||
var ranCustomCompiler = false | ||
let vm = new NodeVM({ | ||
compiler: (code, filename) => { | ||
ranCustomCompiler = true | ||
assert.equal(filename, '/a/b/c.js') | ||
} | ||
}) | ||
vm.run("module.exports = working: true", '/a/b/c.js') | ||
assert.equal(ranCustomCompiler, true); | ||
}) | ||
it('disabled require', () => { | ||
@@ -521,2 +546,42 @@ let vm = new NodeVM; | ||
it('can require a module inside the vm', () => { | ||
let vm = new NodeVM({ | ||
require: { | ||
external: true | ||
} | ||
}) | ||
vm.run("require('mocha')", __filename); | ||
}) | ||
it('can deny requiring modules inside the vm', () => { | ||
let vm = new NodeVM({ | ||
require: { | ||
external: false | ||
} | ||
}) | ||
assert.throws(() => vm.run("require('mocha')", __filename), err => { | ||
assert.equal(err.name, 'VMError'); | ||
assert.equal(err.message, 'Access denied to require \'mocha\''); | ||
return true; | ||
}) | ||
}) | ||
it('can whitelist modules inside the vm', () => { | ||
let vm = new NodeVM({ | ||
require: { | ||
external: ['mocha'] | ||
} | ||
}) | ||
assert.ok(vm.run("require('mocha')", __filename)) | ||
assert.throws(() => vm.run("require('unknown')", __filename), err => { | ||
assert.equal(err.name, 'VMError'); | ||
assert.equal(err.message, "The module 'unknown' is not whitelisted in VM."); | ||
return true; | ||
}) | ||
}) | ||
it('arguments attack', () => { | ||
@@ -523,0 +588,0 @@ let vm = new NodeVM; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83405
15
2016