I'm trying to run untrusted javascript code in linux + node.js with the sandbox module but it's broken, all i need is to let users write javascript programs that printout some text. No other i/o is allowed and just plain javascript is to be used, no other node modules. If it's not really possible to do, what other language do you suggest for this kind of task? The minimal feature set i need is some math, regexes, string manipulation, and basic JSON functions. Scripts will run for let's say 5 seconds tops and then the process would be killed, how can i achieve that?
vm2 is a sandbox that can run untrusted code with whitelisted Node's built-in modules. Securely!
Untrusted environment is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page. Sometimes it is useful to run code with inputs from untrusted users, untrusted code, etc.
The assert module. The basis for most Node unit testing is the built-in assert module, which tests a condition and, if the condition isn't met, throws an error. Node's assert module is used by many third-party testing frameworks. Even without a testing framework, you can do useful testing with it.
The node:vm module enables compiling and running code within V8 Virtual Machine contexts.
All libraries I've seen mentioned in such questions (vm2
, jailed
) are trying to isolate the node
process itself. Those kind of "jails" are constantly broken and highly dependent on future upgrades to node
's standard library to not expose another attack vector.
An alternative would be to use the V8::Isolate
class directly. It is meant to isolate JavaScript in Google Chrome & node
, so you can expect it to be fully maintained, and more secure than you, I or a single library maintainer would ever be able to do. This class is only able to run "pure" JavaScript
. It has the full ECMAScript implementation, but no browser API or node
API.
This is what is used by Cloudflare
for their Worker product.
deno
, the new language developed by node
's creator, has an ambition of sandboxing by default using exactly the same thing and exposing parts of the standard library depending on the flags you enable.
In a node
environment, you can use isolated-vm
. It's an amazing library that creates v8::Isolate
d subprocesses with the code you want to run in isolation.
It provides methods to pass values and functions to the isolate and back. This is not as trivial to use than most of the "jailing" libraries, but guarantees you an actual sandboxing of the JavaScript code.
As it's "pure" JavaScript, the only escapes are the ones you provide under the form of injected functions.
Also, it gets automatically updated with each node
version, as it uses node
's own v8::Isolate
.
One of the main pains is that if you want to inject libraries in your script, you will likely need to use a package bundler like webpack
in order to bundle everything in a single script that can be used by the library.
I personally use it to run user-provided code in a crawler to extract information from a webpage using user provided code, and it works wonders.
I've recently created a library for sandboxing the untrusted code, it seems to fit the demands (executes a code in a restricted process in case of Node.js, and in a Worker inside a sandboxed iframe for a web-browser):
https://github.com/asvd/jailed
There is an opportunity to export the given set of methods from the main application into the sandbox thus providing any custom API and set of privilliges (that feature was actually the reason why I decided to make a library from scratch). The mentioned maths, regexp and string -related stuff is provided by the JavaScript itself, anything additional may be explicitly exported from outside (like some function for communicating with the main application).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With