想象一个场景,我想连续调用用户提供的Javascript代码,如下面的示例所示,其中getUserResult
某个用户(不是我自己)编写的函数是:
for (var i = 0; i < N; ++i) {
var x = getUserResult(currentState);
updateState(currentState, x);
}
如何在浏览器和/或Node.js中执行这种代码,而没有任何安全隐患?
更一般而言,如何执行不允许修改甚至无法读取当前网页或任何其他全局状态的Javascript函数?是否有类似浏览器中的“ JS虚拟机”?
JSFiddle如何确保您无法运行任何恶意代码(至少可以仿冒您的登录名,在页面的生存期内运行一个bot,如果没有做更糟糕的事情)?还是不能完全确保?
经过深思熟虑,并在此主题的其他发布者的帮助下(非常感谢您的帮助!),我找到了问题的第一批答案。不过,我在这里重写了我的答案,因为它总结了概念,还为您提供了一些实际的代码供您尝试。
通常,针对此问题有两种解决方案:我们可以在隔离的环境中使用iframe
或Worker
运行代码,因此无法读取或写入当前页面的信息(这是我的第一个主要的安全问题)。
有更完整的沙盒解决方案,例如Google Caja,(默认情况下)该代码也可以在中运行其代码iframe
。Caja不仅提供沙箱JS,还提供HTML和CSS。但是,似乎不再非常积极地维护它了。不确定是否有很好的支持?
正如Juan Garcia所建议的那样,我将使用Web Worker API,但这不是完整的故事。即使工作人员无法直接从托管页面访问任何内容,仍然存在相当多的安全风险。该站点列出了Worker上下文中可用的所有内置插件。
这个JSFiddle演示了一种在window
Context上下文之外运行代码字符串而无需通过服务器的方法,正如注释中指出的那样,这仍然是不安全的。
我对此进行了扩展,并采用了基于黑名单的方法,通过删除以下所有内容来禁用所有外部通信:
Worker
WebSocket
XMLHttpRequest
importScripts
然而,实际上最安全的方法是白名单方法(在此提及),因为它将在未来保持安全(假设任何列入白名单的全局变量的语义永远不会以允许将来访问更多内容的方式改变发布;这是一个合理的假设)。
我最终在浏览器WumpusGame中实现了白名单方法,该方法允许您在玩游戏时编写自己的AI脚本,几年前。源代码在这里。您可以看到,白名单是在GuestScriptContext中维护的,而工作进程是由HostScriptContext管理的。
该GameScriptContext显示如何使用它。
它具有多种功能,包括来宾<br>主机通信,来宾可以在主机上执行非特权操作(如果它具有安全令牌甚至是特权操作),以及更多功能。
注意:它不能与某些扩展一起很好地使用,因为它们会阻止覆盖全局变量(当我尝试运行它时,它抱怨自己TEMPORARY
是其中之一)。解决的办法是将其列入白名单,或者弄清楚如何使其与现代浏览器安全功能或仅针对安全性的扩展(例如AdBlock等)完美搭配。
从理论上讲,该游戏在这里可以玩,但是由于上述原因,它似乎无法在Chrome中运行(而且我还没有尝试过其他浏览器)。
更多参考:
Worker
没有单独文件的情况下运行。本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句