pitboss-ng
v2.0.1
Published
Run untrusted code in a seperate process using VM2 module. With timeout and memory limit management
Downloads
1,613
Readme
Pitboss-NG (next gen)
A module for running untrusted code
var Pitboss = require('pitboss-ng').Pitboss;
var untrustedCode = "var a = !true;\n a";
var sandbox = new Pitboss(untrustedCode, {
memoryLimit: 32*1024, // 32 MB memory limit (default is 64 MB)
timeout: 5*1000, // 5000 ms to perform tasks or die (default is 500 ms = 0.5 s)
heartBeatTick: 100 // interval between memory-limit checks (default is 100 ms)
});
sandbox.run({
context: { // context is an object of variables/values accessible by the untrusted code
'foo': 'bar', // context must be JSON.stringify positive
'key': 'value' // = no RegExp, Date, circular references, Buffer or more crazy things
},
libraries: {
myModule: path.join(__dirname, './my/own/module'),
// will be available as global "myModule" variable for the untrusted code
'crypto': 'crypto', // you can also require system/installed packages
'_': 'underscore' // require underscore the traditional way
}
}, function callback (err, result) {
// result is synchronous "return" of the last line in your untrusted code, here "a = !true", so false
console.log('Result is:', result); // prints "Result is: false"
sandbox.kill(); // don't forget to kill the sandbox, if you don't need it anymore
});
// OR other option: libraries can be an array of system modules
sandbox.run({
context: {}, // no data-variables are passed to context
libraries: ['console', 'lodash'] // we will be using global "lodash" & "console"
}, function callback (err, result) {
// finished, kill the sandboxed process
sandbox.kill();
});
Runs JS code and returns the last eval'd statement
var assert = require('chai').assert;
var Pitboss = require('pitboss-ng').Pitboss;
var code = "num = num % 5;\nnum;"
var sandbox = new Pitboss(code);
sandbox.run({context: {'num': 23}}, function (err, result) {
assert.equal(3, result);
sandbox.kill(); // sandbox is not needed anymore, so kill the sandboxed process
});
Allows you to pass you own libraries into sandboxed content
var assert = require('chai').assert;
var Pitboss = require('pitboss-ng').Pitboss;
var code = "num = num % 5;\n console.log('from sandbox: ' + num);\n num;"
var sandbox = new Pitboss(code);
sandbox.run({context: {'num': 23}, libraries: ['console']}, function (err, result) {
// will print "from sandbox: 5"
assert.equal(3, result);
sandbox.kill(); // sandbox is not needed anymore, so end it
});
Handles processes that take too damn long
var assert = require('chai').assert;
var Pitboss = require('pitboss-ng').Pitboss;
var code = "while(true) { num % 3 };";
var sandbox = new Pitboss(code, {timeout: 2000});
sandbox.run({context: {'num': 23}}, function (err, result) {
assert.equal("Timedout", err);
sandbox.kill();
});
Doesn't choke under pressure (or shitty code)
var assert = require('chai').assert;
var Pitboss = require('pitboss-ng').Pitboss;
var code = "Not a JavaScript at all!";
var sandbox = new Pitboss(code, {timeout: 2000});
sandbox.run({context: {num: 23}}, function (err, result) {
assert.include(err, "VM Syntax Error");
assert.include(err, "Unexpected identifier");
sandbox.kill();
});
Doesn't handle this! But 'ulimit' or 'pidusage' does!
var assert = require('chai').assert;
var Pitboss = require('pitboss-ng').Pitboss;
var code = "var str = ''; while (true) { str = str + 'Memory is a finite resource!'; }";
var sandbox = new Pitboss(code, {timeout: 10000});
sandbox.run({context: {num: 23}}, function (err, result) {
assert.equal("Process failed", err);
sandbox.kill();
});
And since Pitboss-NG forks each process, ulimit kills only the runner