开发者

Javascript Sandbox?

开发者 https://www.devze.com 2023-02-11 03:36 出处:网络
Would it be possible to sandbox user-submitted Javascript by overriding various functions such as alert, window.location, and eval?

Would it be possible to sandbox user-submitted Javascript by overriding various functions such as alert, window.location, and eval?

I'm not looking for a perfect solution. I'm sure some people would still find a way to rearrange divs to spell out swear words or something malicious, but if I could disable page redirects 100% reliably I would be mostly happy.

I tried in Chrome, and doing something like

context={}; //use this to prevent `this` from being `window`
context.f=function(){
  var window=null,location=null,eval=function(){};
  console.log(window); //also the other two
};
context.f();

seems promising. If I replace the console line with user-submitted code (checking for paren balancing), would that be an absurdly bad idea or a mildly bad idea? On Chrome I can still break things by going through this to Function and redefining th开发者_开发知识库ings, but that would be acceptable to me.


You can use Microsoft Web Sandbox or Google Caja.


Here are two more possible solutions (disclaimer: I just started looking for this myself, so I am not an expert).

This is very interesting, uses web workers to sandbox untrusted code:

https://github.com/eligrey/jsandbox

even though, I wonder if that is maintaned anymore, or if the following html5 "sandbox" iframe attribute supersedes it:

http://www.w3schools.com/html5/att_iframe_sandbox.asp


vm.js is a javascript virtual machine implemented in pure coffeescript(should run in relatively old browsers) and can be used as a lightweight in-process sandbox. It can break infinite loops and shields global objects from modifications.


Depending on what this needs to do, you could always run the javascript in a document-context-free environment, like through Rhino, and then grab the results server-side and clean/insert those.


You could also try Douglas Crockford's AdSafe, though it does limit the possibilities of JavaScript.


Masking the globals with local variables is not secure actually. Preprocessing the untrusted code with tools like Google Caja may help, but it's not necessary:

  • For a web-browser simply running a code in a Worker is enough - it seems to be pretty restricted nowadays. See update below

  • For Node.js you may fork() in a sandboxed process and execute the code there (using the child_process module).

There are also some libraries for simplifying the sandboxing, one of those created by myself is Jailed (there's also a demo with JS-Console which executes user-submitted code in a sandbox).

Update: obviously I was wrong, the worker is not secure by itself, as it can access some of same-origin stuff, like IndexedDB for instance. I have submitted a related question. The solution is to additionally put the worker into a sasndboxed iframe, which is also implemented in my Jailed library.


Use HTML5 "sandbox" iframe attribute.


I made a javascript function for this.

function evalUnsafe(userCode) {
  var vars = [];

  var legal = {console: 'console', alert: 'alert'};
  for(var b in this) {
    if (!(b in legal)) {
      vars.push(b);
    }
  }

  var funcs = vars.join(",");
  var code = "(function sandbox(" + funcs + ") {function runthis() {eval(" + JSON.stringify(userCode) + ");};var a = new runthis();})();";
  eval(code);
}

And then you can do this

Example 1:

evalUnsafe("alert(window);");

Example 2 (from a php file):

evalUnsafe(<?php echo json_encode(file_get_contents("example.js"));?>);

You can download it from here:

https://github.com/oyvindrestad/javascriptsandbox

0

精彩评论

暂无评论...
验证码 换一张
取 消