Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safely sandbox and execute user submitted JavaScript?

I would like to have the ability to let users submit arbitrary JavaScript code, which is then sent to a Node.JS server and safely executed before the output is sent back to multiple clients (as JSON). The eval function comes to mind, but I know this has multiple security concerns (the user submitted code would be able to access Node's File API, etc). I have seen some projects like Microsoft Web Sandbox and Google Caja which allow execution of sanitized markup and script (for embedding third-party ads on websites), but it seems that these are client-side tools and I'm not sure if they can be safely used within Node.

Is there a standard way to sandbox and execute non-trusted JavaScript in Node, getting the output. Is it a mistake to try and do this server-side?

EDIT: It's not important that the user be able to leverage the full capabilities of JavaScript, in fact it would be preferable to be able to pick and choose which APIs would be provided to the user code.

EDIT: I am going to go ahead and update with what I found. This Sandcastle module (bcoe/sandcastle) seems to aim to do what I have in mind. Not sure how secure it is, but since I this is not for anything too important I think I'll if try it. I'll add my own answer if I'm able to successfully do this.

like image 243
Cory Gross Avatar asked Jul 07 '13 14:07

Cory Gross


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.

Can the Nodejs VM be considered safe to run untrusted code in a sandboxed environment?

It is not possible to build a secure sandbox or run untrusted code using the vm module in any capacity, full stop.

Which core module in node can you use to compile and run JavaScript code in a sandbox environment?

The node:vm module enables compiling and running code within V8 Virtual Machine contexts.


2 Answers

You can use sandbox support in nodejs with vm.runInContext('js code', context), sample in api documentation:

https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options

const util = require('util'); const vm = require('vm');  const sandbox = { globalVar: 1 }; vm.createContext(sandbox);  for (var i = 0; i < 10; ++i) {     vm.runInContext('globalVar *= 2;', sandbox); } console.log(util.inspect(sandbox));  // { globalVar: 1024 } 

WARN: As pointed by "s4y" it seems to be flawled. Please look at the comments.

like image 70
ton Avatar answered Sep 18 '22 13:09

ton


One alternative would be to use http://github.com/patriksimek/vm2:

$ npm install vm2 

then:

const {VM} = require('vm2'); const vm = new VM();  vm.run(`1 + 1`);  // => 2 

as mentioned in comments of other answers.

I don't know how secure it is, but it at least claims that it runs untrusted code securely (in its README). And I couldn't find any obvious security issues so far as solutions suggested in other answers here.

like image 43
Hiroshi Ichikawa Avatar answered Sep 20 '22 13:09

Hiroshi Ichikawa