Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running untrusted javascript code on server in sandbox

I can't seem to figure out how to set up a node sandbox, which can run untrusted code safely, and allows a user to interact with the program through api calls (sys in and out). I'm trying to set up a console in the browser for users to run their own code from the server.

Are there any node packages that support this, or do I need to write my own node VM? Thanks.

Edit: I want a user to be able to write readline() and have the program wait at the breakpoint for data to be transferred in. similarly console.log()'s output should redirect to the response of the input api call.

like image 246
X88B88 Avatar asked Aug 19 '17 03:08

X88B88


People also ask

What is JavaScript sandboxing?

Sandboxed JavaScript is a simplified subset of the JavaScript language that provides a safe way to execute arbitrary JavaScript logic from Google Tag Manager's custom templates. To provide a safe execution environment, some features of JavaScript are restricted or removed.

Is vm2 secure?

vm2 is a sandbox that can run untrusted code with whitelisted Node's built-in modules. Securely!


Video Answer


1 Answers

You can use the vm2 module and run almost any code that comes with user input in a secure way.

You can even define whether the user-supplied code will have access to require native Node modules or other modules via relative path or even define whether a code coming from the user input can make an external call.

You can envelop and execute this "untrusted" code in a try/catch to observe catastrophic failures or even set a timeout so that this run does not overwhelm.

quick example

const {VM} = require('vm2');
const vm = new VM();

vm.run(`process.exit()`); // TypeError: process.exit is not a function

using "request" module "bultin" for access external resource

const {NodeVM} = require('vm2');
const vm = new NodeVM({
    require: {
        external: true // allow all modules or use Array for one e.g: ['request']
    }
});    

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.
        }
    })
`, 'vm.js');

By default the entry is compiled into javascript but you can pass a function with your custom compiler.

like image 103
Lauro Moraes Avatar answered Oct 15 '22 10:10

Lauro Moraes