2

I am currently considering issues of running user-supplied code in node. I have two issues:

  1. The user script must not read or write global state. For that, I assume I can simply spawn of a new process. Are there any other considerations? Do I have to hide the parent process from the child somehow, or is there no way a child can read, write or otherwise toy with the parent process?
  2. The user script must not do anything funky with the system. So, I am thinking of disallowing any system calls. How do I achieve this? (Note that if I can disallow the process module, point 1 should be fixed as well, no?)
5
  • 1
    What OS are you running on? Commented Mar 22, 2014 at 2:48
  • I want this to work on all systems (at least Windows and Linux). Commented Mar 22, 2014 at 5:40
  • Does this answer your question? How to run untrusted code serverside? Commented Mar 27, 2020 at 10:34
  • @Jerska From what I understand, these days, vm2 seems to be the way to go Commented Mar 28, 2020 at 11:45
  • This is an automatic message when marking as a duplicate.vm2 would be the way to go to run a node process, but requires careful maintenance on any new node release. If you're looking to execute raw JavaScript, isolated-vm would be a better alternative. Commented Mar 31, 2020 at 8:36

1 Answer 1

4

You are looking for the runInNewContext function from the vm module (vm documentation).

When you use this function it creates a VERY limited context. You'll need to pass anything you want into the sandbox object which become global objects. For example: You will need to include console in the sandbox object if you want your untrusted code to write to the console.

Another thing to consider: Creating a new context is a VERY expensive operation - takes extra time and memory to do. Seriously consider if you absolutely need this. Also seriously consider how often this is going to happen.

Example:

var vm = require('vm');
var sandbox = {
    console: console,
    msg: "this is a test",
};

vm.runInNewContext('console.log(msg);', sandbox, 'myfile.vm');

// this is a test

More to consider: You will want to create a new process to run this in. Even though it's in a new context it's still in the same process that it's being called from. So a malicious user could simply set a never ending for loop so that it never exits. You'll need to figure out logic to know when something like this happens so that you can kill the process and create a new one.

Last thought: A new context does not have setTimeout or setInterval. You may or may not want to add these. However, if you create a setInterval in the untrusted code and the untrusted code never stops it then it will continue on forever. You'll need to figure a way to end the script, it's probably possible I just haven't looked into it.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. This is extremely helpful. The last point has also been brought to my attention recently as a major issue when running Node as a server: Scripts can easily kill the whole thing. Are there standard "system tools" for Node to fix that? About the cost of context (and even process) creation: Would you recommend pooling those? Like for example, Apache just creates a threadpool of 200 threads by default. I imagine, a similar strategy might be useful for my approach (and restart contexts/processes if they die), what do you think?
I honestly don't know enough to help. I was looking into doing something similar with running untrusted code. However, I quickly moved away from it due to these issues and didn't do enough research to find out exactly what I did need. I didn't want a single malicious user causing issues with any other users code at any point. So for my application I scraped the idea of user submitted code altogether.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.