允许用户输入 HTML 的安全子集

信息安全 php xss html
2021-08-20 01:50:56

我最近在 Code Review 上发布了这个问题,建议我向你们提问。

基本上,这将用于允许用户生成格式化的内容。它被放置在 HTML 标记中,因此我不必担心攻击者会破坏属性。如果不清楚,这里有一个例子:

<div>
Generated content
</div>

编辑:我没有将内容插入到属性中,所以转义引号不是问题。我知道我仍然需要检查用户生成内容中的不良属性,这是脚本的大部分内容。

我已经确定我很容易受到发布恶意链接或发布跟踪图像的攻击者的攻击,但这是我愿意接受的。如果没有白名单 URL,我认为您无法阻止这种情况,这也会大大降低用户的自由度。如果有一种可行的方法来修复这个漏洞,我很想听听。

我已经阅读了OWASP XSS 备忘单,并且我认为我已经涵盖了所有这些基础。

除了备忘单之外,我还需要担心什么?我错过了什么吗?我的代码是面向未来的吗?我是不是有点过头了?我应该切换到 BBCode 还是 Markup?

当前代码

3个回答

使用白名单时,您走在正确的道路上,但实施防弹是很棘手的。

即您的链接可以通过编写以下内容被愚弄执行JS:

<a href="JAVASCRIPT:xxx">xss</a>

此外,尤其是旧浏览器可能会在 img src 等中执行 JS。

我建议您使用HTMLPurifier,除了 XSS 之外,它还可以帮助您处理损坏的 HTML(标签嵌套等)。

总结:使用 HTML sanitizer,但只能与内容安全策略结合使用,因为不断有新的方法可以绕过过滤器。

在您自己处理以允许列入白名单的 HTML 标记的子集通过之后,您应该通过 HTML 清理程序传递您的内容。

除了使用某种 HTML 消毒剂外,还建议在包含用户 HTML 内容的页面上实施内容安全策略这是一种浏览器实现的机制,如果用户确实设法插入恶意脚本,它将停止执行内嵌 JavaScript。您可以将 CSP 设置为.js允许外部内容(在您的域上或您列入白名单的其他内容 - 例如 Google 托管库)。

这些步骤将确保如果用户确实输入javascript:alert('foo');或任何作为链接,它将不会被执行。但是,如果您允许img标签和a标签,它们可能指向任何网址。他们可以跟踪,但document.cookie由于 CSP ,会话信息将无法与他们一起发送(例如)。

随着浏览器和网络语言的发展,最终在 HTML sanitizer 中总会发现漏洞,例如版本的 HTML Purifier (<= v4.1.0) 中的漏洞。这就是为什么我建议将这两种方法相互结合,以确保一种方法中的差距不会让您容易受到攻击。

不建议您尝试自己实现。如果您决定使用用户提供的 HTML,您应该在此处查看 OWASP ESAPI for php 。