How to run user-provided Javascript without security issues (like jsFiddle, jsBin, etc.)?
Asked Answered
O

3

6

I need to run a Javascript function that is completely written by the user. I provide him a skeleton, but the details are for him to specify, e.g.

function main(model, console) {
    // the user can enter anything here
    // ideally, he would only be allowed to 
    // use the methods that "model" and "console" provide, e.g.
    var item = model.getItems();
    console.log("Found " + item.length + " items.");
}

For the application to work, the user only needs to access methods and properties of the parameters (he explicitely doesn't require document or window access or send XMLHttpRequests).

I have already read several articles about the eval() function and how you can use it to run code. I also read other articles on StackOverflow (how jsFiddle runs code, eval in general, etc.), but I'm still not sure how to do it properly.

First of all: what are the real issues of eval()? What can an attacker do and how can you prevent it (with whitelists, blacklists or user input sanitizing libraries)? Can anyone explain in depth how jsFiddle and such websites execute user input?

Orphrey answered 1/9, 2014 at 8:37 Comment(3)
A malicious user could use eval to get your app's cookies (like user session tokens, which would allow them to impersonate the logged-in user), any state held in memory on your client and make requests to get further state from your server. It could post any data to another server. In short, they could own your application.Donau
jsfiddle puts the user's document in an IFRAME, and runs it in a different domain (fiddle.jshell.net instead of jsfiddle.net), so it has no access to the jsfiddle application.Orrin
Can you explain in detail? How do they communicate and what are the limitations of this approach?Orphrey
T
5

What can evaled code do? It could do essentially anything your code can do; it is evaluated in the same context.

Creating a system to allow third-party code to run while protecting yourself is extremely hard and rife with opportunities to shoot yourself in the foot. Trying to cook up your own solution is a very bad idea.

Luckily there are a number of well tested projects created by very smart people that endeavor to make it safe to run third party code. The two most prominent ones would be Google Caja and Douglas Crockford's ADsafe.

As @Barmar noted, JSFiddle runs the code in an iframe on a different domain, this causes the browser to not allow the code in the iframe access to the parent page due to the Same Origin Policy.

Trilobate answered 1/9, 2014 at 9:32 Comment(0)
P
7

The proper way to run untrusted JavaScript is to put it into a sandboxed environment. Here is the technique used by a Jailed library written by myself for exactly the mentioned purpose:

For Node.js:

  1. Create a subprocess;

  2. Load the code as a string (read the file contents in case you have its path);

  3. Add use strict; at the beginning of the code (in order to prevent breaking the sandbox using arguments.callee.caller);

  4. Evaluate that string in a separate context using vm.runInNewContext(), where the provided sandbox only exposes some basic methods like setTimeout().

For the web-browser:

  1. Create an iframe with a sandbox attribute (so that its content obeys the cross-origin policy and therefore cannot access the main application);

  2. Create a web-worker inside that iframe (so that user-submited code will get its own thread and therefore will not freeze the UI)

Piscatelli answered 18/1, 2015 at 14:51 Comment(1)
While this was a fine choice at the time the answer was written, it is not a safe choice in 2023 for Node.js use: github.com/asvd/jailed/issues/57Sentimentality
T
5

What can evaled code do? It could do essentially anything your code can do; it is evaluated in the same context.

Creating a system to allow third-party code to run while protecting yourself is extremely hard and rife with opportunities to shoot yourself in the foot. Trying to cook up your own solution is a very bad idea.

Luckily there are a number of well tested projects created by very smart people that endeavor to make it safe to run third party code. The two most prominent ones would be Google Caja and Douglas Crockford's ADsafe.

As @Barmar noted, JSFiddle runs the code in an iframe on a different domain, this causes the browser to not allow the code in the iframe access to the parent page due to the Same Origin Policy.

Trilobate answered 1/9, 2014 at 9:32 Comment(0)
S
0

Chiming in from 2023: for the browser, you can still use jailed, as mentioned in an earlier response.

However, for Node.js, this is not a safe choice any longer.

While Node.js does not directly expose it, the underlying v8 JavaScript implementation has a feature called Isolates which is intended for this purpose. The isolated-vm npm library can be used to obtain access to this interface in Node.js code. The documentation may seem daunting, but the example at the end (which I won't duplicate here) is more straightforward and shows that even the amount of RAM consumed can be restricted.

Sentimentality answered 14/7, 2023 at 14:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.