在 WebForm 标签中转义 HTML 实体并避免 HTML 注入?

Posted

技术标签:

【中文标题】在 WebForm 标签中转义 HTML 实体并避免 HTML 注入?【英文标题】:Escape HTML-entities and avoid HTML-injection in WebForm Label? 【发布时间】:2012-08-31 15:01:18 【问题描述】:

所以,我认为我是一名“资深”的 ASP.NET WebForms 开发人员;但是,我最近遇到了这个问题,并且(不愉快地)对输出 没有 转义感到惊讶:

<asp:Label Text='<%# Eval("UserData") %>' runat="server" />

在 Eval 返回 "&lt;h1&gt;joke is on you" 或对页面的正确呈现/安全性更有害的地方进行成像。

直接使用标签而不是&lt;%# %&gt; 的原因是,错误地假定,“UserData”的内容将被正确地转义为 html。然而,这显然不是的情况,上述场景导致在 HTML 标记中创建 &lt;h1&gt; 元素。

那么问题可以提炼为:

给定任意用户输入,即显示为“纯文本”,将数据插入页面(在跨度中)并正确转义的简单/可靠/安全方法是什么?

如上所述,它应该在数据绑定控件的上下文中运行。我知道HttpUtility.HtmlEncode,但我希望考虑仍然使用控件的想法 - 也许我错过了这个任务的标准控件 - 安全地表示这个案例,没有需要包装Eval。如果这是基于逻辑或经验的误导,最好将其包含在回复中。我不会否认我在这种情况下使用 Label 是完全不合适的。

不幸的是,由于需要在 SharePoint 2010 上下文中运行,我将 ASP.NET 定位为 .NET 3.5,而不是 ASP.NET 4。

【问题讨论】:

【参考方案1】:

怎么样:

<asp:Label Text='<%#: Eval("UserData") %>' runat="server" />

这会转义 eval 的输出,这仅适用于 .NET 4。

对于 .NET 3.5,解决方案可以是:

代码隐藏:

public object EvalEncode(object container, string expression)

  string ouput = DataBinder.Eval(container, expression).ToString();
  return HttpUtility.HtmlEncode(ouput);

标记:

<%# EvalEncode(Container.DataItem, "Text") %>

与其使用HttpUtility.HtmlEncode,不如使用AntiXSS 库。对于 .NET 4 用户,它已经支持到框架中。

【讨论】:

服务器标签中是否有&lt;#: 的链接/参考来完成此答案?我只能找到&lt;:,它“就像&lt;= 一样带有转义”,这是 ASP.NET 4 中的新功能(不幸的是,无论它是什么,我都被 ASP.NET 3/3.5 卡住了)。 +1 很酷,每当我“向上移动”时,这将是一件非常方便的事情。不幸的是,我被困在 .NET 3.5 中(我现在已经在帖子中包含了该信息)。 "伟大的思想相似或愚蠢.." :-) 这是我刚刚实现的(谢天谢地,我所有的用户控件共享一个公共基类,所以很容易),但略有不同,我有一个方法string HtmlEncode(object value),所以调用是HtmlEncode(Eval("Text"))。明确地必须使用 Container.DataItem 对我来说并不合适(如果有办法以 动态范围的方式 访问它,那就太好了!) 这就像魔术。谢谢。对于像我这样不得不费力比较文本的人来说,.NET 4 行中的区别是“Eval”之前的冒号。【参考方案2】:

使用 microsoft 提供的Microsoft Web Protection Library(Anti-XSS 库)用于此类目的。

安全很难,不要试图自己做。总有一些更聪明的黑客。

你使用它如下:

<asp:Label Text='<%= Microsoft.Security.Application.AntiXss.HtmlEncode(Eval("UserData")) %>' runat="server" />

【讨论】:

该页面上的 cmets(对于“1 星”)吓到我了 :( 有一个示例说明在这种情况下如何使用它(或相关部分)? 您只需要在向页面呈现任何用户数据之前调用HtmlEncode。在分配文本时这样做应该很好。 我想知道它比&lt;asp:Label Text='&lt;%= HtmlUtility.HtmlEncode(Eval("UserData")) %&gt;' runat="server" /&gt; 有什么优势,除非 HtmlUtility.HtmlEncode 不可靠.. 我不认为我会使用它(作为另一个依赖项),但 +1 链接可能帮助其他需要完整库(和额外工具)支持的人。 这比HtmlUtility.HtmlEncode严格很多。它将检查文本中的 html 标签、脚本标签、css。 我只需要确保我不能在输出中引入 HTML 标签。标签是否包含在内容中并不重要(例如,我不关心检测恶意尝试),但它们(尤其是&lt;s)应该相应地转义。【参考方案3】:

您可以使用&lt;asp:Literal ...&gt;&lt;/asp:Literal&gt; 控件代替标签。文字有一个 Mode 属性,您可以使用它来告诉控件对其输出进行 html 编码。

而不是这个:

<asp:Label Text='<%# Eval("UserData") %>' runat="server" />

尝试使用:

<asp:Literal Text='<%# Eval("UserData") %>' Mode="Encode" runat="server"></asp:Literal>

【讨论】:

+1 啊,很有趣!我不知道Mode 选项(我认为文字是.. 总是文字)。如果这个属性也存在于 Label 中(用于 CssClass/wrapping span 和其他功能),那就太好了.. @pst 好吧,您可以将它们组合起来,因为您可以将文字放在标签内:&lt;asp:Label ...&gt;&lt;asp:Literal ...&gt;&lt;/asp:Literal&gt;&lt;/asp_Label&gt;,而不是使用标签上的 Text 属性。 这只是变得比它的价值更复杂:) 我正在考虑创建一个“SafeLabel”控件包装器,但希望有一个标准的“safe-Label”控件。不幸的是,情况似乎并非如此。

以上是关于在 WebForm 标签中转义 HTML 实体并避免 HTML 注入?的主要内容,如果未能解决你的问题,请参考以下文章

ASCII 到 HTML 实体在 Java 中转义

如何在 XML 中转义 & 符号,以便将它们呈现为 HTML 中的实体?

iOS中转义后的html标签如何还原

在没有 Owasp 库的情况下,如何在 Java 中转义 HTML 属性值?

如何在 django 标签中转义双引号?

为啥必须在 XML 属性中转义 <?