【问题标题】:Filtering JavaScript out of HTML从 HTML 中过滤 JavaScript
【发布时间】:2023-11-19 00:45:02
【问题描述】:

我有一个将 HTML 传递给服务器的富文本编辑器。然后将该 HTML 显示给其他用户。我想确保该 HTML 中没有 JavaScript。有没有办法做到这一点?

另外,如果有帮助,我正在使用 ASP.NET。

【问题讨论】:

  • 属性是否需要保留?
  • 是的,我正在使用一个名为可爱编辑器的富文本编辑器,它可以处理某些事情,例如删除
  • 所以要真正回答你的问题,是的,我需要保留属性才能充分利用 RTE

标签: javascript html xss filtering sanitization


【解决方案1】:

确保某些 HTML 标记不包含任何 JavaScript 的唯一方法是过滤掉所有不安全的 HTML 标记和属性,以防止 Cross-Site Scripting (XSS)。

但是,通常没有可靠的方法通过名称明确删除所有不安全的元素和属性,因为某些浏览器可能会解释您在设计时甚至不知道的内容,从而为恶意用户打开了一个安全漏洞。这就是为什么您最好采用白名单方法而不是黑名单方法。也就是说,只允许您确定安全的HTML标签,默认剥离所有其他标签。事实上,只有一个意外允许的标签会使您的网站容易受到 XSS 攻击。


白名单(好方法)

请参阅HTML sanitisation 上的这篇文章,其中提供了一些具体示例,说明为什么应该将其列入白名单而不是列入黑名单。从该页面引用:

以下是潜在危险的 HTML 标记和属性的不完整列表:

  • script,可能包含恶意脚本
  • appletembedobject,可自动下载并执行恶意代码
  • meta,可能包含恶意重定向
  • onloadonunload 和所有其他可能包含恶意脚本的 on* 属性
  • stylelinkstyle属性,可以包含恶意脚本

Here 是另一个有用的页面,它建议了一组 HTML 标记和属性以及通常安全允许的 CSS 属性,以及推荐的做法。

黑名单(通常是不好的方法)

尽管许多网站过去(和现在)都使用黑名单方法,但几乎从来没有真正需要它。 (安全风险总是超过白名单对授予用户的格式化功能的潜在限制。)您需要非常了解它的缺陷。

例如,this page 给出了一个列表,列出了您可能想要删除的所谓“所有”HTML 标记。简单地观察一下,您应该注意到它包含的元素名称数量非常有限;浏览器很容易包含一个专有标签,该标签会无意中允许脚本在您的页面上运行,这本质上是黑名单的主要问题。


最后,我强烈建议您为 .NET 使用 HTML DOM 库(例如众所周知的 HTML Agility Pack),而不是 RegEx 来执行清理/白名单,因为它会更加可靠。 (很可能创建一些可以欺骗正则表达式的非常疯狂的混淆 HTML!无论如何,适当的 HTML 阅读器/编写器使系统的编码变得更加容易。)

希望这能让您大致了解为了完全(或至少最大限度地)防止 XSS 需要设计什么,以及在考虑未知因素的情况下执行 HTML 清理的重要性。

【讨论】:

  • 在写我的答案时,我看到了你的答案,看起来不错。实际上,我必须在 C# 中编写一些代码来做你可能尝试做的事情。防止任何 XSS 攻击。我已经制作了一个配置文件来了解哪些 html 标签具有哪些属性是允许的。但是您将需要根据您的代码进行大量测试。 (就像诺多林所说的那样)。
  • 黑名单永远不会起作用,因为其他浏览器可能会解释您甚至不知道的标签。您需要一种白名单方法。
  • 在我这边,我更多的是列入白名单而不是列入黑名单。对于样式属性,您需要删除行为等。
  • @sleske:黑名单在实践中确实有效,但我同意它可能存在风险。同样,如果您将某些标签列入白名单,那么可能会有一些用户可能想要使用的无害标签是不允许的。尽管如此,这无疑是一个较小的邪恶。我将更新帖子以提及白名单,这很重要。想取消反对票吗?
  • @Noldorin:黑名单确实有效,因为它使攻击更加困难,但它总是会留下漏洞;我正是这个意思。无论如何,现在我真的很喜欢你的回答:-)。 +1
【解决方案2】:

这是我使用白名单方法的方法 (Javascript 和 Python 代码)

https://github.com/dcollien/FilterHTML

我为允许的 HTML 子集定义了一个规范,这只是应该通过这个过滤器的内容。 还有一些选项可以净化 URL 属性,只允许某些方案(如 http:、ftp: 等)并禁止那些会导致 XSS/Javascript 问题的方案(如 javascript:,甚至是数据:)

编辑:这不会在所有情况下为您提供 100% 开箱即用的安全性,但可以智能地使用并与其他一些技巧结合使用(例如检查 url 是否在同一个域中,以及正确的内容-type等)它可能是你需要的

【讨论】:

    【解决方案3】:

    正如 Lee Theobald 所指出的,这是一个非常危险的计划。根据定义,您不能通过过滤/黑名单生成“安全”HTML,因为用户可能会将您没有想到的内容放入 HTML 中(或者甚至在您的浏览器版本中不存在,但在其他版本中存在)。

    唯一安全的方法是白名单方法,即去除除纯文本和某些特定 HTML 结构之外的所有内容。顺便说一句,*.com 就是这样做的 :-)。

    【讨论】:

      【解决方案4】:

      如果您希望更改 html,以便用户可以看到 HTML 代码本身。对所有 ''、'&' 和 ';' 进行字符串替换。例如 '

      如果您希望 html 正常工作,最简单的方法是删除所有 HTML 和 Javascript,然后仅替换 HTML。不幸的是,几乎无法确定删除所有 javascript 并只允许 HTML 的方法。

      例如,您可能希望允许图像。但是你可能不知道你可以这样做

      <img src='evilscript.js'>
      

      它可以运行该脚本。它变得非常不安全非常快$。这就是为什么像*和本网站这样的大多数网站都使用特殊的降价语言的原因。这使得允许格式化但不允许恶意 javascript 变得更加容易。

      【讨论】:

        【解决方案5】:

        您可能想检查一些基于浏览器的 WYSIWYG 编辑器(例如 TinyMCE)是如何工作的。他们通常会删除 JS,并且似乎在这方面做得不错。

        【讨论】:

        • 是的,他们这样做了,但如果你有点“黑客”,你可以将 tinymce 编辑器置于文本模式,然后当你保存数据时,用户仍有可能修改带有 javascript 的文本。
        • 嗯,任何 JS 都是如此。您始终可以禁用 JS 并提交您想要的任何内容。相反,您应该考虑使用 ASP.NET 可以做什么,因为您希望在您拥有控制权的服务器上保护自己,而不是在您几乎没有控制权的浏览器上保护自己。
        【解决方案6】:

        最简单的做法是使用正则表达式去除标签。麻烦的是,你可以在没有脚本标签的情况下做很多讨厌的事情(例如,嵌入不可靠的图像,链接到其他带有讨厌 Javascript 的网站)。通过将小于/大于字符转换为其 HTML 实体形式(例如

        如果您想要更强大的解决方案,过去我曾使用AntiSamy 来清理传入的文本,以便安全查看。

        【讨论】:

        • 实际上,“用正则表达式去除标签”并不是最好的建议。
        • 我对 AntiSamy 不熟悉,但我建议您在使用前确保其设计良好(即首先采用白名单方法)。此外,即使是简单的解决方案,正则表达式绝对也不可行。
        • 这是一种白名单方法
        • "这是一种白名单方法" NO!剥离标签被列入黑名单。您是否 100% 确定会删除所有标签?如果攻击者离开了关闭角的后卫怎么办?你的正则表达式能抓住这个吗? => 你未能加入黑名单。
        • -1 危险的错误建议。此外,关于“带有正则表达式部分”:关于 HTML 和正则表达式的规范问题的强制性链接:RegEx match open tags except XHTML self-contained tags