如何沙箱不受信任的用户提交的JavaScript内容?

时间:2012-08-31 05:58:59

标签: javascript iframe sandbox same-origin-policy

我需要在我的网站上提供用户提交的脚本(有点像jsfiddle)。我希望脚本能够以安全的方式在访问者浏览器上运行,与它们所服务的页面隔离。由于代码是由用户提交的,因此无法保证它是值得信赖的。

现在我可以想到三个选择:

  • 在来自其他域的iframe中投放用户提交的内容,并依赖于同源策略。这需要设置一个我想尽可能避免的额外域名。我相信这就是jsfiddle的做法。该脚本仍然会造成一些损害,例如更改top.location.href,这不太理想。 http://jsfiddle.net/PzkUw/
  • 使用sandbox attribute 。我怀疑浏览器不能很好地支持它。
  • 在提供脚本之前清理脚本。我宁愿不去那里。

上述是否还有其他解决方案或建议?

更新

如果我怀疑,第一个选项是最佳解决方案,除了更改顶部窗口位置之外,恶意脚本可以做什么,以及如何防止这种情况?我可以操纵或拒绝某些基于静态代码分析的脚本,但这是hard给定了可以访问对象的方式数量以及一般静态分析javascript的难度。至少,它需要一个完整的解析器和一些复杂的规则(一些,但我怀疑并非所有,在JSLint中都存在)。

4 个答案:

答案 0 :(得分:26)

创建一个定义良好的消息接口,并使用JavaScript Web Worker获取要沙箱的代码。 HTML5 Web Workers

Web Workers无权访问以下DOM对象。

  • 窗口对象

  • 文档对象

  • 父对象

因此,他们无法重定向您的网页或更改其上的数据。

您可以创建一个模板和一个定义良好的消息传递接口,以便用户可以创建Web工作者脚本,但您的脚本将对操作的内容有最终决定权。

编辑评论由Jordan Gray插入一个似乎可以执行上述操作的JavaScript库。 https://github.com/eligrey/jsandbox

答案 1 :(得分:5)

一些可能对您的应用程序有所帮​​助的工具的想法 - 它们从两个不同的方向攻击问题:Caja将不受信任的JavaScript代码编译为安全的东西,而AdSafe定义了一个可安全使用的JavaScript子集。

卡哈

Caja

  

Caja编译器是一种可以安全地嵌入您网站的第三方HTML,CSS和JavaScript的工具。它支持嵌入页面和嵌入式应用程序之间的丰富交互。 Caja使用对象功能安全模型来实现各种灵活的安全策略,以便您的网站可以有效地控制嵌入式第三方代码可以对用户数据执行的操作。

称为AdSafe

AdSafe

  

ADsafe可以安全地将访客代码(例如第三方脚本广告或小部件)放在网页上。 ADsafe定义了一个强大的JavaScript子集,允许访客代码执行有价值的交互,同时防止恶意或意外损坏或入侵。 ADsafe子集可以通过JSLint等工具进行机械验证,因此无需人工检查即可查看访客代码的安全性。 ADsafe子集还实施了良好的编码实践,增加了访客代码正确运行的可能性。

答案 2 :(得分:3)

如上所述,主要浏览器已经支持sandbox的{​​{1}}属性,但我还建议使用混合解决方案:在沙盒iframe中启动Web工作者。这将提供一个单独的线程,并保护事件不受信任的代码中的沙盒iframe的DOM。这就是我的Jailed库的工作原理。此外,您可以通过将任何功能集导出到沙箱来解决任何限制。

答案 3 :(得分:-4)

如果您希望通过删除某些代码来访问它,可以通过删除它来说明窗口文档元素来实现它通过将它包装在一个闭包中,其中这些是本地空变量:

(function(window, document, parent /* Whatever you want to remove */){
  console.log(this);      // Empty object
  console.log(window);    // undefined
  console.log(document);  // undefined
  console.log(parent);    // undefined
}).call({});

使用空对象调用它很重要,否则将指向窗口对象