Javascript沙盒?

15

是否可以通过覆盖诸如alertwindow.locationeval之类的各种函数来沙盒用户提交的Javascript?

我不是在寻找完美的解决方案。我相信有些人仍然会找到一种方法来重新排列div以拼出脏话或其他恶意内容,但如果我能够可靠地100%禁用页面重定向,我就会大部分满意。

我在Chrome中尝试过,做了一些像

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();

看起来很有前途。如果我用用户提交的代码替换console行(检查括号平衡),这是非常糟糕的想法还是比较糟糕的想法?在Chrome中,通过访问this到函数并重新定义内容仍然可以破坏事情,但对我来说这是可以接受的。


使用iframe。否则,请确保摆脱setTimeout和setInterval,因为第一个参数可以是字符串,该字符串将被eval处理。 - Ivo Wetzel
2
还要不要忘记隐藏(原型)ObjectNumber,特别是Function,以及全局对象(window)的所有属性。如果您在IFrame中“隔离”用户脚本,请确保它们无法以任何方式访问框架集合。 - Martijn
@Martijn,隐藏原型是否可能?他们不是可以从(function(){}).constructor或类似的地方访问它们吗? - Loyal Tingley
相关:https://dev59.com/Zk7Sa4cB1Zd3GeqP2ERs - Ates Goral
8个回答

11

6
我们能否通过向Microsoft的沙箱中倒入糟糕的代码来打破它?这些代码必定会泄露出去。 - Raynos
1
这两个都使用服务器端翻译器,对吧?如果可能的话,我想在客户端上做。这更多是一个“能否完成”问题,而不是“我需要解决方案”的问题。 - Loyal Tingley
@Loyal:如果服务器可以做到,客户端也可以做到。 - SLaks

4

JSandbox 不再维护。来源 - Joncom

3

vm.js 是一个使用纯粹的 CoffeeScript 实现的 JavaScript 虚拟机(应该可以在相对较旧的浏览器中运行),可用作轻量级进程内沙箱。它可以打破无限循环并保护全局对象免受修改。


2
将全局变量用本地变量屏蔽实际上并不安全。使用像Google Caja这样的工具对不受信任的代码进行预处理可能有所帮助,但这并非必要:
  • 对于在Web浏览器中运行的代码,仅在Worker中运行代码似乎已经足够严格了请参见下面的更新

  • 对于Node.js,您可以在沙盒进程中fork()并在那里执行代码(使用child_process模块)。

还有一些简化沙盒化的库,其中之一是我创建的Jailed(还有一个demo,其中JS-Console在沙盒中执行用户提交的代码)。

更新:显然我是错的,worker本身并不安全,因为它可以访问一些同源内容,比如IndexedDB。我已经提交了一个相关问题的链接。解决方法是将worker放入沙箱iframe中,这也在我的Jailed库中实现了。

2

根据需要执行的操作,您可以在无文档上下文环境中运行javascript,例如通过Rhino,在服务器端获取结果并清理/插入它们。


这可以使用 AJAX 和任何服务器端 JS 引擎(Rhino、SpiderMonkey、MSScriptControl、seed、node.js、JSDB、EmbedThis EJScript)来完成。这完全取决于您的服务器端技术。 - Martijn
我想在客户端运行它,虽然这可能是一个选项。谢谢 :) - Loyal Tingley

2
您也可以尝试使用Douglas Crockford的AdSafe,但它会限制JavaScript的可能性。

1
使用HTML5的"sandbox" iframe属性。

1
我为此编写了一个 JavaScript 函数。
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);
}

然后你可以这样做:

示例1:

evalUnsafe("alert(window);");

例子2(来自一个php文件):
evalUnsafe(<?php echo json_encode(file_get_contents("example.js"));?>);

您可以从这里下载它:

https://github.com/oyvindrestad/javascriptsandbox


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接