如何在用户生成的 HTML 中防止 Javascript 注入攻击

IT技术 javascript html regex parsing code-injection
2021-01-26 23:32:08

我正在保存用户提交的 HTML(在数据库中)。我必须防止 JavaScript 注入攻击。我见过的最有害的是 .js 文件中的 JavaScript style="expression(...)"

除此之外,相当多的有效用户内容将包括特殊字符和 XML 结构,因此我希望尽可能避免使用白名单方法。(列出每个允许的 HTML 元素和属性)。

JavaScript 攻击字符串示例:

1.

"Hello, I have a
<script>alert("bad!")</script>
problem with the <dog>
element..."
"Hi, this <b
style="width:expression(alert('bad!'))">dog</b>
is black."

有没有办法阻止这样的 JavaScript,而其余部分完好无损?

到目前为止,我唯一的解决方案是使用正则表达式来删除某些模式。它解决了情况 1,但不解决了情况 2。

环境本质上是 Microsoft 堆栈:

  • SQL Server 2005
  • C# 3.5 (ASP.NET)
  • JavaScript 和 jQuery。

我希望阻塞点是 ASP.NET 层 - 任何人都可以制作错误的 HTTP 请求。

编辑

谢谢大家的链接。假设我可以定义我的列表(内容会包含很多数学和编程结构,所以白名单会很烦人),我还有一个问题:

什么样的解析器可以让我删除“坏”部分?不好的部分可能是整个元素,但是那些驻留在属性中的脚本呢?我不能随意删除< a hrefs >

6个回答

你认为是这样吗?看看这个

无论您采用何种方法,您都绝对需要使用白名单。这是对您在网站上允许的内容接近安全的唯一方法。

编辑

不幸的是,我不熟悉 .NET,但您可以查看 stackoverflow 自己与 XSS 的战斗(https://blog.stackoverflow.com/2008/06/safe-html-and-xss/)以及当时的代码用于解析发布在此站点上的 HTML:Archive.org 链接- 显然您可能需要更改此设置,因为您的白名单更大,但这应该可以帮助您入门。

感谢您的反馈。我担心白名单是答案。:)
2021-03-13 23:32:08
如果您的方法是删除危险的东西,您的代码将容易受到注入。唯一安全的方法是拥有一个特别允许的元素和属性的白名单。
2021-03-16 23:32:08
在这里解释一下白名单是什么以及它如何操作/删除坏东西?
2021-03-25 23:32:08
谢谢,我实际上正在使用该站点作为测试平台。我已经成功删除了任何看起来像 <script> 的东西,所以我需要得到那些不......也就是说,表达式:,javascript:,vbscript:等等。你能建议一个可以做到这一点的解析器吗?
2021-04-05 23:32:08
杰夫,试试这个字符串:<scr<script>ipt>是的 XSS!黑名单将不起作用。无论您的白名单是否长,都无法将其列入黑名单。如果您想阅读更多关于此的文章,OWASP 网站可以提供很多帮助。
2021-04-05 23:32:08

在我看来,元素和属性的白名单是唯一可以接受的选择。任何不在您的白名单上的东西都应该被删除或编码(将 <>&" 更改为实体)。另外一定要检查您允许的属性中的值。

少一点,你就会面临问题——已知的漏洞利用或将来会发现的漏洞。

唯一真正安全的方法是使用白名单。对所有内容进行编码,然后将允许的代码转换回来。

我已经看到相当先进的尝试只禁止危险代码,但它仍然不能很好地工作。尝试安全地捕捉任何人能想到的一切相当了不起的,并且很容易对一些根本不危险的东西进行烦人的替换。

我发现了困难的方法。我们现在正在使用转义和白名单。
2021-03-17 23:32:08

目前最好的选择是使用这样的内容安全策略标头:

Content-Security-Policy: default-src 'self';

这将阻止加载内联和外部脚本、样式、图像等,因此浏览器只会加载和执行来自同一来源的资源。

但是,它不适用于旧浏览器。

@DanielWu 是的,但您可以将 CDN 域或文件哈希列入白名单
2021-03-24 23:32:08
这会阻止我们使用 CDN 吗?
2021-03-28 23:32:08

基本上,正如 Paolo 所说,您应该尝试关注用户被允许做的事情,而不是试图过滤掉他们不应该做的事情。

保留允许的 HTML 标记列表(例如 b、i、u...)并过滤掉其他所有内容。您可能还想删除允许的 HTML 标记的所有属性(例如,因为您的第二个示例)。

另一种解决方案是引入所谓的 BB 代码,这是很多论坛使用的。它的语法与 HTML 相似,但首先是允许代码白名单的想法,然后将其转换为 HTML。例如, [b]example[/b] 将导致example确保在使用 BB 代码时仍然预先过滤掉 HTML 标签。

我担心的内容将包括许多数学和编程结构(XML、C# 等),所以我很想避免白名单。
2021-04-10 23:32:08