udibo-sandbox

A node.js sandbox.

udibo-sandbox

A node.js sandbox.

npm install udibo-sandbox
  • Run code Asynchronously in a secure environment
  • Code is executed within a virtual machine
  • Virtual machines are stored in a child process
  • It will automatically restart itself when needed
  • Timeout system to abort code that is taking to long to execute
  • Safe to run untrusted code in
  • Ability to whitelist modules that can be used by virtual machines in the sandbox

Warning: Modules that are accessable by a virtual machine are run outside of the virtual machine in the sandbox's child process.

  • timeout: The default timeout in miliseconds for all virtual machines within the sandbox. If undefined the default timeout will be 10000 miliseconds.
  • modules: An array of modules that can be accessed by all virtual machines within the sandbox.

Each sandbox has its own child process that is created with it. Below is an example of how to create a sandbox.

var Sandbox = require("udibo-sandbox");
 
var mySandbox = new Sandbox();
  • name: The name that will be used to reference the virtual machine.
  • path: The path to a javascript file that will be ran within the virtual machine.
  • timeout: The timeout in miliseconds for the module to use.
  • modules: An array of modules that can be accessed by the virtual machine.

This function will add a virtual machine to the sandbox.

mySandbox.addVm("empty");
mySandbox.addVm("helloWorld", "./helloWorld.js");

The virtual machines created in this example are stored in the virtualMachines object.

//empty 
mySandbox.virtualMachines["empty"];
 
//helloWorld 
mySandbox.virtualMachines["helloWorld"];
  • name: The name of the virtual machine that you want to reload.

This function will revert a virtual machine to its original state.

mySandbox.reloadVm("helloWorld");

This is another way to revert a virtual machine to its original state.

mySandbox.virtualMachines["helloWorld"].reload();
  • name: The name of the virtual machine that you want to remove.

This function will remove a virtual machine from the sandbox.

mySandbox.removeVm("helloWorld");

This is another way to remove a virtual machine from the sandbox.

mySandbox.virtualMachines["helloWorld"].remove();
  • vmName: The name of the virtual machine that you want to run code in.
  • code: The code that you want to run in the virtual machine.
  • callback: A function to call after the code has been ran in the virtual machine.

This function will run code in a virtual machine.

mySandbox.run("empty", "a = 1");
 
mySandbox.run("empty", "a", function(errresult){
    if(err) throw err;
    console.log("Value of a: ".concat(result));
});
//Value of a: 1 
 
mySandbox.run("empty", "var b; a *= 5; b = 4*a; a++", function(errresult){
    if(err) throw err;
    console.log("Value of a: ".concat(result));
});
//Value of a: 5 
 
mySandbox.run("empty", "[a, b]", function(errresult){
    if(err) throw err;
    console.log("Value of a: ".concat(result[0]));
    console.log("Value of b: ".concat(result[1]));
});
//Value of a: 6 
//Value of b: 20 
  • code: The code that you want to run in the virtual machine.
  • callback: A function to call after the code has been ran in the virtual machine.

This is another way to run code in a virtual machine.

var emptyVm = mySandbox.virtualMachines["empty"];
emptyVm.run("a = 1");
 
emptyVm.run("a", function(result){
    console.log("Value of a: ".concat(result));
});
//Value of a: 1 
 
emptyVm.run("var b; a *= 5; b = 4*a; a++", function(result){
    console.log("Value of a: ".concat(result));
});
//Value of a: 5 
 
emptyVm.run("[a, b]", function(result){
    console.log("Value of a: ".concat(result[0]));
    console.log("Value of b: ".concat(result[1]));
});
//Value of a: 6 
//Value of b: 20 

The default timeout is 10 seconds. If any code sent to a virtual machine takes longer than the timeout the child process will be killed and restarted. If there was a callback set it will be executed without the result being defined. Anything sent after the code that timed out will be executed after the virtual machines are added to the new child process.

The timeout is stored in miliseconds, you can change at any time if needed.

//Change timeout to 5 seconds 
mySandbox.timeout = 5000;
 
mySandbox.run("empty", "var a = 1; for(var i = 0; i < 1000000000; i++){ a += i; }; a", function(errresult){
    if(err)
        console.error(err.message);
    else
        console.log("Value of a: ".concat(result));
});
//[Error: Request has timed out] 

If this is set it will be used instead of sandbox.timeout.

  • module: A module that you want all virtual machines within a sandbox to have access to.

A module prefixed with '.' is relative to where the currently executing script is called from.

mySandbox.addGlobalModule("util");
 
mySandbox.run("empty", "util = require(\"util\"); util.log(\"Hello world!\");");
//3 Jan 06:50:49 - Hello world! 
  • modules: An array of modules that you want all virtual machines within a sandbox to have access to.

This just calls sandbox.addGlobalModule for each module in the array.

mySandbox.addGlobalModules(["console", "os"]);
 
mySandbox.run("empty", "console = require(\"console\"); os = require(\"os\"); console.log(os.platform());");
//linux 
  • module: A module that you want all virtual machines within a sandbox to no longer have access to.

This just prevents a virtual machine from being able to require a module. If the virtual machine already used require to get it before you remove access to it, it will still be able to use the module.

If a virtual machine is given access to a module directly it will still have access. If you added a module to a virtual machine you must remove it from the virtual machine.

mySandbox.removeGlobalModule("util");
 
mySandbox.run("empty", "util = require(\"util\"); util.log(\"Hello world!\");", function(errresult){
    if(err)
        console.error(err.message);
});
//[Error: Cannot find module 'util'] 
  • modules: An array of modules that you want all virtual machines within a sandbox to no longer have access to.

This just calls sandbox.removeGlobalModule for each module in the array.

mySandbox.removeGlobalModules(["console", "os"]);
 
mySandbox.run("empty", "console = require(\"console\"); os = require(\"os\"); console.log(os.platform());", function(errresult){
    if(err)
        console.error(err.message);
});
//[Error: Cannot find module 'console'] 
  • vmName: The name of the virtual machine that you want to add a module to.
  • module: The module that you want to give the virtual machine access to.

This gives only one virtual machine access to a module which the other virtual machines within the sandbox will not have access to.

mySandbox.addModule("hello", "util");
 
mySandbox.run("hello", "util = require(\"util\"); util.log(\"Hello world!\");");
//3 Jan 06:50:49 - Hello world! 
  • module: The module that you want to give the virtual machine access to.

This is another way to give a virtual machine access to a module.

helloVm = mySandbox.virtualMachines["hello"];
helloVm.addModule("util");
 
helloVm.run("util = require(\"util\"); util.log(\"Hello world!\");");
//3 Jan 06:50:49 - Hello world! 
  • vmName: The name of the virtual machine that you want to add modules to.
  • modules: An array of modules that you want the virtual machine to have access to.

This just calls sandbox.addModule for each module in the array.

mySandbox.addModules("hello", ["console", "os"]);
 
mySandbox.run("hello", "console = require(\"console\"); os = require(\"os\"); console.log(os.platform());");
//linux 
  • modules: An array of modules that you want the virtual machine to have access to.

This is another way to give a virtual machine access to modules.

helloVm = mySandbox.virtualMachines["hello"];
helloVm.addModules(["console", "os"]);
 
helloVm.run("console = require(\"console\"); os = require(\"os\"); console.log(os.platform());");
//linux 
  • vmName: The name of the virtual machine that you want to remove a module from.
  • module: The module that you want the virtual machine to no longer have access to.

This just prevents a virtual machine from being able to require a module.

mySandbox.removeModule("hello", "util");
 
mySandbox.run("hello", "util = require(\"util\"); util.log(\"Hello world!\");", function(errresult){
    if(err)
        console.error(err.message);
});
//[Error: Cannot find module 'util'] 
  • module: The module that you want the virtual machine to no longer have access to.

This is another way to prevent a virtual machine from being able to require a module.

helloVm = mySandbox.virtualMachines["hello"];
helloVm.removeModule("util");
 
helloVm.run("util = require(\"util\"); util.log(\"Hello world!\");", function(errresult){
    if(err)
        console.error(err.message);
});
//[Error: Cannot find module 'util'] 
  • vmName: The name of the virtual machine that you want to remove modules from.
  • module: An array of modules that you want the virtual machine to no longer have access to.

This just calls sandbox.removeModule for each module in the array.

mySandbox.removeModules("hello", ["console", "os"]);
 
mySandbox.run("hello", "console = require(\"console\"); os = require(\"os\"); console.log(os.platform());", function(errresult){
    if(err)
        console.error(err.message);
});
//[Error: Cannot find module 'console'] 
  • module: An array of modules that you want the virtual machine to no longer have access to.

This is another way to prevent a virtual machine from being able to require modules.

helloVm = mySandbox.virtualMachines["hello"];
helloVm.removeModules(["console", "os"]);
 
helloVm.run("console = require(\"console\"); os = require(\"os\"); console.log(os.platform());", function(errresult){
    if(err)
        console.error(err.message);
});
//[Error: Cannot find module 'console'] 

Examples can be located in the examples directory. Currently there is only one example. If you would like to add examples feel free to do so.