我需要在我的网站上提供用户提交的脚本(有点像jsfiddle)。我希望脚本能够以安全的方式在访问者浏览器上运行,与它们所服务的页面隔离。由于代码是由用户提交的,因此无法保证它是值得信赖的。
现在我可以想到三个选择:
top.location.href
,这不太理想。 http://jsfiddle.net/PzkUw/ 上述是否还有其他解决方案或建议?
更新
如果我怀疑,第一个选项是最佳解决方案,除了更改顶部窗口位置之外,恶意脚本可以做什么,以及如何防止这种情况?我可以操纵或拒绝某些基于静态代码分析的脚本,但这是hard给定了可以访问对象的方式数量以及一般静态分析javascript的难度。至少,它需要一个完整的解析器和一些复杂的规则(一些,但我怀疑并非所有,在JSLint中都存在)。
答案 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编译器是一种可以安全地嵌入您网站的第三方HTML,CSS和JavaScript的工具。它支持嵌入页面和嵌入式应用程序之间的丰富交互。 Caja使用对象功能安全模型来实现各种灵活的安全策略,以便您的网站可以有效地控制嵌入式第三方代码可以对用户数据执行的操作。
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({});
使用空对象调用它很重要,否则此将指向窗口对象