Skip to content
GitHub Twitter

What is Sandbox and How to create one in NodeJs

What is Sandbox and How to create one in NodeJs

What is Sandbox

A sandbox is an environment virtual space in which set of programming instructions can be executed in isolation, without effect on the surrounding network or its applications. Sandboxes are used in both web development and cybersecurity to safely test, monitor, and experiment with software.

NodeJs Sandbox

A sandbox environment in NodeJs can be created by using the following ways:

VM2

VM2 is a NodeJs sandbox that can run untrusted code with whitelisted Node's built-in modules as well as external modules, it has various security features to prevent vulnerability os untrusted code. Following is the example of a sandbox timeout

const {NodeVM} = require('vm2');

const vm = new NodeVM({
    require: {
        external: true,
        builtin: ['timers/promises'],
        root: './'
    }
});

async function test() {
    const sandboxTimeoutFunc = vm.run(`
        exports.executeTimeout = async (args) => {
            console.log(args);
            console.log("started at", Math.floor(new Date().getTime() / 1000));
        
            const timersPromises = require('timers/promises');
            await timersPromises.setTimeout(3000);
        
            console.log("ended at", Math.floor(new Date().getTime() / 1000));
        };
    `);
    await sandboxTimeoutFunc.executeTimeout({"foo": "bar"});
}

test();

Execute sandbox code with custom node modules or a lambda layer:

const {NodeVM} = require('vm2');

const vm = new NodeVM({
    require: {
        external: true,
        builtin: ['timers/promises']
    }
});

async function test() {
    const sandboxPostReqFunc = vm.run(`
        const axios = require("axios");
        exports.execute = async (args) => {
            console.log(args);
            console.log("started at", Math.floor(new Date().getTime() / 1000));
        
            await axios.post("https://sometestserver.com/todos", { params: { hello: "world" }});
        
            console.log("ended at", Math.floor(new Date().getTime() / 1000));
        };
    `, '/opt/nodejs/node_modules'); // specify your custom path here
    await sandboxPostReqFunc.execute({"foo": "bar"});
}

test();

NodeVM

The node:vm module enables compiling and running code within V8 Virtual Machine contexts. The vm module in Node.js is available by default — no need for NPM. Once it is implemented, we can define the actual JS code we want to execute. To execute the code in the VM, we call runInThisContext.

const vm = require('node:vm');

const code = `console.log('hello from the sandbox vm')`;
vm.runInThisContext(code) // hello from the vm

executing code with node modules

const nodeVM = require('node:vm');
const timersPromises = require('timers/promises');

async function runScript(code, context = {}, options = {}) {
    return new Promise((resolve, reject) => {
        const { timeout = 120 * 1000, breakOnSigint = true } = options;
        const script = new nodeVM.Script(`(async()=>{${code}})()`);
        script.runInContext(nodeVM.createContext({
            ...context,
            resolve,
            reject,
        }), {
            timeout,
            breakOnSigint,
        });
    });
}

(async () => {
    const context = {
        timersPromises: timersPromises,
    }
    const sandboxCode = `
        console.log("execution started at", Math.floor(new Date().getTime() / 1000));
        await timersPromises.setTimeout(3000);
        console.log("execution ended at", Math.floor(new Date().getTime() / 1000));
        resolve();
    `;
    await runScript(sandboxCode, context)
})();

Additional Resources