在 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 返回 "<h1>joke is on you"
或对页面的正确呈现/安全性更有害的地方进行成像。
直接使用标签而不是<%# %>
的原因是,错误地假定,“UserData”的内容将被正确地转义为 html。然而,这显然不是的情况,上述场景导致在 HTML 标记中创建 <h1>
元素。
那么问题可以提炼为:
给定任意用户输入,即显示为“纯文本”,将数据插入页面(在跨度中)并正确转义的简单/可靠/安全方法是什么?
如上所述,它应该在数据绑定控件的上下文中运行。我知道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 用户,它已经支持到框架中。
【讨论】:
服务器标签中是否有<#:
的链接/参考来完成此答案?我只能找到<:
,它“就像<=
一样带有转义”,这是 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
。在分配文本时这样做应该很好。
我想知道它比<asp:Label Text='<%= HtmlUtility.HtmlEncode(Eval("UserData")) %>' runat="server" />
有什么优势,除非 HtmlUtility.HtmlEncode 不可靠.. 我不认为我会使用它(作为另一个依赖项),但 +1 链接可能帮助其他需要完整库(和额外工具)支持的人。
这比HtmlUtility.HtmlEncode
严格很多。它将检查文本中的 html 标签、脚本标签、css。
我只需要确保我不能在输出中引入 HTML 标签。标签是否包含在内容中并不重要(例如,我不关心检测恶意尝试),但它们(尤其是<
s)应该相应地转义。【参考方案3】:
您可以使用<asp:Literal ...></asp:Literal>
控件代替标签。文字有一个 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 好吧,您可以将它们组合起来,因为您可以将文字放在标签内:<asp:Label ...><asp:Literal ...></asp:Literal></asp_Label>
,而不是使用标签上的 Text 属性。
这只是变得比它的价值更复杂:) 我正在考虑创建一个“SafeLabel”控件包装器,但希望有一个标准的“safe-Label”控件。不幸的是,情况似乎并非如此。以上是关于在 WebForm 标签中转义 HTML 实体并避免 HTML 注入?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 XML 中转义 & 符号,以便将它们呈现为 HTML 中的实体?