我们有一个简单的博客系统,允许用户输入 html 和 JavaScript 来构建博客页面。我知道允许 javascript 打开 xss 攻击的大门。然而,我们确实需要允许用户插入 JavaScript,例如允许用户插入包含 JavaScript 的谷歌广告代码。问题是如何在防止 xss 的同时允许 JavaScript。我假设 https 会保护 cookie 并防止 cookie 被盗,但 stackoverflow 上的用户却说不然。
允许 JavaScript 输入但防止 XSS 的解决方案
https完全是关于加密和确保服务器身份以防止其他人监听流量。因此,它对同源策略范围内的恶意 JavaScript 代码毫无帮助。
cookie 上有一个名为httpOnly的标志,它阻止现代浏览器上的简单 JavaScript 代码访问 cookie。但这并不能解决问题,它只是让漏洞利用变得不那么简单:JavaScript 代码可以直接触发具有当前用户权限的表单提交。由于 JavaScript 在同一个域中,它可以访问CSRF令牌。浏览器将在表单提交中包含 cookie,而无需 JavaScript 代码访问它。(还有一些围绕 HttpOnly 的错误,例如某些浏览器允许从 XMLHttpRequest 对象读取 cookie。)
此外,JavaScript 作者可以将当前页面内容替换为“您的会话已超时,请重新登录”及其自己的登录表单。但他添加的表单并没有指向您服务器的登录 URL,而是指向他控制的服务器。或者更微妙的是,提交按钮的事件处理程序中可能存在跨域 Ajax 调用。
有一个相当简单的解决方案,分两步:
- 过滤所有不受信任的标记,包括所有 JavaScript。如果您使用的是 PHP,则可以使用HTML-Purifier。所有常用语言都有类似的库。
- 提供无害的占位符(“小部件”)。因此,与其让您的用户直接嵌入 JavaScript 代码,他们必须编写类似
<div id="googleadd">identifier</div>
. 一段受信任的全局 JavaScript 代码可以将那些代码片段替换为真正的添加代码。确保正确转义输入参数。这会稍微限制您的用户可以做的事情,但是很容易涵盖所有常见的用例。
谷歌一下确实有意义,因为那里已经有许多 Widget 库;尽管它们中的大多数仍然需要 JavaScript 调用。
HTTPS 不会阻止窃取 cookie,HTTPOnly 标志可以。我建议(如果可能的话)让用户可以在页面中包含一个“小部件”库并进行配置。然后,您可以只插入带有配置参数的 JavaScript 代码,而无需用户编写 JavaScript 代码。
如果您允许您的用户插入他们自己的 JavaScript 代码,他们可以执行诸如更新您的博客系统的登录表单以将凭据发送到另一台服务器,这样如果某些用户访问了恶意博客页面并决定登录到您的系统在该页面上,他的凭据可能会被泄露。
不,HTTPS 并不能阻止这种威胁。
如果必须允许您的用户在页面中包含他们编写的 Javascript,这是一个非常具有挑战性的问题。你想要的是某种Javascript 沙箱。@Mike Samuel 对 Caja 的推荐是 Javascript 沙盒技术的不错选择。这个领域的其他可能性包括 Microsoft 的 Web Sandbox、Yahoo 的 AdSafe、Facebook 的 FBJS,以及我可能错过的其他可能性。
请理解,虽然解决方案确实存在,但部署起来并不容易。您偶然发现了网络安全中的一个难题;网络并不是为了支持这种事情而设计的,因此,解决方案最终必然成为一项相当复杂的技术。因此,您可能需要有能力的开发人员的支持才能将这些解决方案之一部署和集成到您的网站中。
无耻但相关的插件:
来自code.google.com/p/google-caja/
Caja 允许网站安全地嵌入来自第三方的 DHTML Web 应用程序,并实现嵌入页面和嵌入应用程序之间的丰富交互。它使用对象能力安全模型来允许范围广泛的灵活安全策略,以便包含页面可以有效地控制嵌入式应用程序对用户数据的使用,并允许小工具防止小工具的 UI 元素之间的干扰。