WebUtility.HtmlEncode 和 AntiXssEncoder.HtmlEncode 有什么区别?

Agr*_*dha 3 c# antixsslibrary asp.net-core-2.1

AntiXssEncoder.HtmlEncode 仅支持.Net 框架。当我们的应用程序位于 .net core 2.1 中时,我可以使用 WebUtility.HtmlEncode 进行 Antixss 吗?

Dai*_*Dai 8

长话短说:

\n
\n

AntiXssEncoder.HtmlEncode 仅支持.Net 框架。当我们的应用程序位于 .net core 2.1 中时,我可以使用 WebUtility.HtmlEncode 进行 Antixss 吗?

\n
\n

正确的

\n

但我想强调的是,不存在“反 XSS HTML 编码器”这样的东西,因为所有正确实现的 HTML 编码器在正确使用时都会保护您的网站免受 XSS 攻击。

\n
    \n
  • (我不知道微软为什么命名它AntiXssEncoder,但考虑到当时的主要HtmlEncode实现实际上是有缺陷的,并且不安全可能与它有关,但现在那已经是古老的历史了。)
  • \n
\n

在.NET Core 2.1中,您需要使用System.Net.WebUtility.HtmlEncode.

\n

在其他 .NET 版本(尤其是历史版本)中,事情很复杂,如果你敢的话,请继续阅读......

\n

为什么AntiXssEncoder(又名AntiXssAntiXss.Encoder)存在 - 以及为什么它在 2021 年已过时:

\n
    \n
  • NuGet 包(又名)AntiXssEncoder中的类在移至.AntiXssMicrosoft.Security.Application.AntiXssSystem.Web.Security.AntiXss

    \n
      \n
    • 顺便说一句,其他类:AntiXssEncoderEncoder、 和AntiXss只是相同底层实现的替代 API Encoder
    • \n
    \n
  • \n
  • AntiXssEncoderinSystem.Web.Security.AntiXss在 .NET Core 2.1 中不可用。但这并不是一个严重的问题:

    \n
      \n
    • Microsoft.Security.Application.AntiXss创建原始版本HttpUtility.HtmlEncode是因为它不编码单撇号字符,因此被认为是不安全的,因此 XSS 攻击可能针对.aspx使用单撇号分隔 HTML 属性的 ASP.NET 1.x 和 ASP.NET 2.x WebForms ( ) 页面包含用户指定的值。

      \n
        \n
      • 例如:

        \n
        String userProvidedValue = "bad.gif\' onerror=\'alert()";\n<img src=\'<%= this.Server.HtmlEncode( userProvidedValue ) %>\' />\n
        Run Code Online (Sandbox Code Playgroud)\n

        ...将呈现为:

        \n
        <img src=\'bad.gif\' onerror=\'alert()\' />\n
        Run Code Online (Sandbox Code Playgroud)\n
      • \n
      • 然而,这个问题在 ASP.NET 4.0 中得到了修复,并HttpUtility.HtmlEncode进行了更正,对这些撇号进行 HTML 编码。因此,上面完全相同的代码现在将呈现如下,其中不会显示alert()

        \n
        <img src=\'bad.gif&#39; onerror=&#39;alert()\' />\n
        Run Code Online (Sandbox Code Playgroud)\n
      • \n
      \n
    • \n
    • AntiXssEncoder还支持指定排除的 Unicode 代码点或Char值的列表,添加此列表是因为AntiXssEncoder默认对0xFFFF 以上的所有 Char值(不是代码点!)进行十六进制编码,不幸的是,这意味着即使是完全安全的阿拉伯语、希伯来语、汉字、等将被转义,使原始 HTML 几乎不可读,并使输出 HTML 长度膨胀。

      \n
        \n
      • 例如,(乱码)字符串"\xd9\x84\xd9\x83 \xd8\xa3\xd9\x86 \xd9\x83\xd9\x84\xd8\xa7"将被呈现为"&#x644;&#x643; &#x623;&#x646; &#x643;&#x644;&#x627;"- 这不好。

        \n
      • \n
      • 幸运的是,AntiXssEncoder.MarkAsSafe可以用于由程序员自行决定排除字符范围。

        \n
      • \n
      • 到 .NET Core 2.1 发布时,该类System.Net.WebUtility(当然不要与 混淆System.Web.HttpUtility)得到了改进,因此它不会不必要地对高Char值进行十六进制编码,并且还会对号进行 HTML 编码,因此为什么AntiXssEncoder不再使用需要。

        \n
      • \n
      \n
    • \n
    \n
  • \n
  • 在 .NET Core 3.1(及更高版本,包括 .NET 5 和 .NET 6)中,情况进一步改进,但也有点令人困惑......

    \n
      \n
    • 事情变得更好,因为System.Text.Encodings.Web.HtmlEncoder添加了。这是一个单独的实现(而不是简单地包装WebUtility),它恢复了AntiXssEncoder从编码中排除字符范围的能力,以防万一您需要该功能。但在我看来,这有点极端。\n
        \n
      • 您可以通过调用HtmlEncoder.Create(TextEncoderSettings)已配置的TextEncoderSettings对象并排除所需的字符范围来完成此操作。
      • \n
      \n
    • \n
    \n
  • \n
  • 在 .NET Core 3.1 中,为了向后兼容,微软重新带回了 .NET Core 3.1System.Web.HttpUtility,但这只是 .NET Core 的另一个包装器WebUtility.HtmlEncode

    \n
      \n
    • 它也有HtmlAttributeEncode- ,它编码单撇号。在我看来,没有充分的理由使用这种方法。事实上,我很惊讶微软没有用 来注释它[Obsolete]
    • \n
    \n
  • \n
  • 但是,在 .NET Core(以及 .NET 5 及更高版本)中,没有任何方法可以对文本进行 HTML 编码,以便使用命名实体而不是十六进制编码实体(除了&lt;&gtl&amp;)。

    \n
      \n
    • 以前,AntiXssEncoder.HtmlEncode(bothMicrosoft.SecuritySystem.Web.Security) 方法都有一个useNamedEntities参数,该参数涉及已知实体名称的大型硬编码表,例如,\xc2\xa3用变得&pound;而不是&#127;。\n
        \n
      • 我想他们删除了这个功能,因为你不能安全地使用命名实体,除非你的 HTML 处理管道中的所有其他软件也支持它,并且考虑到它是一个,我预计很多人都会遇到它破坏更新不良的问题下游代码。
      • \n
      • HTML Living Standard(又名“HTML5”)将它们称为字符引用而不是“实体”(SGML DTD 的保留),并将 -syntax 定义&#nnnn;为编码Unicode 代码点的方法,特别是与其他一些字符值相反的方法。编码方案,而以前在 HTML4 中,规范引用 ISO 10646(又名UCS)字符,这不是我们今天所知的 Unicode。(我怀疑如果页面没有使用 Unicode(如 Shift-JIS)编码,浏览器可能会尝试根据文档的编码/代码页映射字符,但我可能是错的)。
      • \n
      \n
    • \n
    \n
  • \n
\n
\n

最后,这是一个比较所有不同的输出的表格HtmlEncode2021 年 .NET 中所有不同方法的输出:

\n

HtmlEncode.NET Framework 4.8 中可用的方法

\n
    \n
  • 请注意,以下HtmlEncode方法被排除在外,因为它们只是其他实现的包装器:\n
      \n
    • System.Web.HttpServerUtility(又名Server.HtmlEncode)仅转发至HttpUtility.HtmlEncode
    • \n
    • System.Web.UI.HtmlTextWriter.WriteEncodedText还转发至HttpUtility.HtmlEncode.
    • \n
    • System.Web.HttpUtility.HtmlEncode:\n
        \n
      • 在 ASP.NET 1.x 和 ASP.NET 2.0(分别是 2001 年和 2005 年)中,这是错误实现的,因此它不会转义撇号。为了满足历史好奇心,我已将该实现的结果包含“System.Web.HttpUtility.HtmlEncode(ASP.NET 1.1 和 2.0)”列中。
      • \n
      • 在 ASP.NET 4.x 中,该HttpUtility.HtmlEncode方法仅转发到System.Web.Util.HttpEncoder.Current.HtmlEncode(s)\n
          \n
        • 请注意,System.Web.Util.HttpEncoder.**Current**可以在运行时替换,这就是 ASP.NET 4.x(我忘了是哪个)的更新如何能够让几乎每个人都使用(当时要好得多),而AntiXssEncoder无需人们更改现有的应用程序代码。整洁的
        • \n
        • 另请注意,System.Web.Util.HttpEncoder.**Current**可以指向任何兼容的实现,而System.Web.Util.HttpEncoder.**Default**`` is _always_ just a wrapper over WebUtility.HtmlEncode`。
        • \n
        \n
      • \n
      \n
    • \n
    • System.Web.Util.HttpEncoder.Default- 如上所述,这只是另一个System.Net.WebUtility包装器。
    • \n
    \n
  • \n
\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n
#输入代码点UTF-8 字节UTF-16 字节System.Net.WebUtility.HtmlEncodeSystem.Text.Encodings.Web.HtmlEncoderSystem.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(false)System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(true)
0abcU+0061 U+0062 U+006361 62 6361 00 62 00 63 00abcabcabcabc
1<U+003C3C3C 00&lt;&lt;&lt;&lt;
2>U+003E3E3E 00&gt;&gt;&gt;&gt;
3&U+00262626 00&amp;&amp;&amp;&amp;
4"U+00222222 00&quot;&quot;&quot;&quot;
5\'U+00272727 00&#39;&#x27;&#39;&#39;
6\xc5\xb8U+009FC2 9F9F 00\xc5\xb8&#x9F;&#159;&#159;
7 U+00A0C2 A0A0 00&#160;&#xA0;&#160;&nbsp;
8\xc3\xbfU+00FFC3 BFFF 00&#255;&#xFF;\xc3\xbf&yuml;
9\xc4\x81U+0101C4 8101 01\xc4\x81&#x101;\xc4\x81\xc4\x81
10~U+007E7E7E 00~~~~
11| `U+007F` | `7F` | `7F 00` |&#x7F;&#127;&#127;
12\xc2\xa3U+00A3C2 A3A3 00&#163;&#xA3;\xc2\xa3&pound;
13\xc3\xbfU+00FFC3 BFFF 00&#255;&#xFF;\xc3\xbf&yuml;
14\xe1\xb8\x82U+1E02E1 B8 8202 1E\xe1\xb8\x82&#x1E02;&#7682;&#7682;
15U+1F4A9F0 9F 92 A93D D8 A9 DC&#128169;&#x1F4A9;&#128169;&#128169;
16U+233B4F0 A3 8E B44C D8 B4 DF&#144308;&#x233B4;&#144308;&#144308;
17U+233B4F0 A3 8E B44C D8 B4 DF&#144308;&#x233B4;&#144308;&#144308;
18\xd9\x84\xd9\x83 \xd8\xa3\xd9\x86 \xd9\x83\xd9\x84\xd8\xa7U+0644 U+0643 U+0020 U+0623 U+0646 U+0020 U+0643 U+0644 U+0627D9 84 D9 83 20 D8 A3 D9 86 20 D9 83 D9 84 D8 A744 06 43 06 20 00 23 06 46 06 20 00 43 06 44 06 27 06\xd9\x84\xd9\x83 \xd8\xa3\xd9\x86 \xd9\x83\xd9\x84\xd8\xa7&#x644;&#x643; &#x623;&#x646; &#x643;&#x644;&#x627;&#1604;&#1603; &#1571;&#1606; &#1603;&#1604;&#1575;&#1604;&#1603; &#1571;&#1606; &#1603;&#1604;&#1575;
\n

过时的和历史的HtmlEncode方法:

\n

包含此表仅出于计算机考古原因。**它不适用于 .NET Framework 4.8,也不适用于任何版本的 ASP.NET Core 和 ASP.NET-for-.NET 5 或更高版本。

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n
#输入代码点UTF-8 字节UTF-16 字节System.Web.HttpUtility.HtmlEncode (ASP.NET 1.1 and 2.0)Microsoft.Security.Application.Encoder.HtmlEncode(false)Microsoft.Security.Application.Encoder.HtmlEncode(true)
0abcU+0061 U+0062 U+006361 62 6361 00 62 00 63 00abcabcabc
1<U+003C3C3C 00&lt;&lt;&lt;
2>U+003E3E3E 00&gt;&gt;&gt;
3&U+00262626 00&amp;&amp;&amp;
4"U+00222222 00&quot;&quot;&quot;
5\'U+00272727 00\'&#39;&#39;
6\xc5\xb8U+009FC2 9F9F 00\xc5\xb8&#159;&#159;
7 U+00A0C2 A0A0 00&#160;&#160;&nbsp;
8\xc3\xbfU+00FFC3 BFFF 00&#255;\xc3\xbf&yuml;
9\xc4\x81U+0101C4 8101 01\xc4\x81\xc4\x81\xc4\x81
10~U+007E7E7E 00~~~
11| `U+007F` | `7F` | `7F 00` |&#127;&#127;
12\xc2\xa3U+00A3C2 A3A3 00&#163;\xc2\xa3&pound;
13\xc3\xbfU+00FFC3 BFFF 00&#255;\xc3\xbf&yuml;
14\xe1\xb8\x82U+1E02E1 B8 8202 1E\xe1\xb8\x82&#7682;&#7682;
15U+1F4A9F0 9F 92 A93D D8 A9 DC&#128169;&#128169;
16U+233B4F0 A3 8E B44C D8 B4 DF&#144308;&#144308;
17U+233B4F0 A3 8E B44C D8 B4 DF&#144308;&#144308;
18\xd9\x84\xd9\x83 \xd8\xa3\xd9\x86 \xd9\x83\xd9\x84\xd8\xa7U+0644 U+0643 U+0020 U+0623 U+0646 U+0020 U+0643 U+0644 U+0627D9 84 D9 83 20 D8 A3 D9 86 20 D9 83 D9 84 D8 A744 06 43 06 20 00 23 06 46 06 20 00 43 06 44 06 27 06\xd9\x84\xd9\x83 \xd8\xa3\xd9\x86 \xd9\x83\xd9\x84\xd8\xa7&#1604;&#1603; &#1571;&#1606; &#1603;&#1604;&#1575;&#1604;&#1603; &#1571;&#1606; &#1603;&#1604;&#1575;
\n

HtmlEncode.NET 5 中的方法

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n
#输入代码点/符文UTF-8 字节UTF-16 字节System.Net.WebUtility.HtmlEncodeSystem.Web.HttpUtility.HtmlEncode (.NET 5)System.Text.Encodings.Web.HtmlEncoder
0abc97 98 9961 62 6361 00 62 00 63 00abcabcabc
1<603C3C 00&lt;&lt;&lt;
2>623E3E 00&gt;&gt;&gt;
3&3826<