简体   繁体   中英

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

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, eg

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?

What can eval ed 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 .

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM