【问题标题】:Escape HTML-entities and avoid HTML-injection in WebForm Label?在 WebForm 标签中转义 HTML 实体并避免 HTML 注入?
【发布时间】: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。

【问题讨论】:

    标签: asp.net webforms escaping html-entities


    【解决方案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”控件。不幸的是,情况似乎并非如此。
    猜你喜欢
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2017-07-31
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多