7

So, I thought I was a "veteran" ASP.NET WebForms developer; however, I came across this recently and was (unpleasantly) surprised that the output is not escaped:

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

Imaging where the Eval returns "<h1>joke is on you" or something more malicious to the correct rendering/security of the page.

The reason there is a Label instead of the <%# %> directly was so that, as incorrectly presumed, the contents of "UserData" would be correctly escaped for HTML. However, this apparently is not the case and the above scenario results in <h1> elements being created in the HTML markup.

Then the question can be distilled as:

Given arbitrary user input, that is to be presented as "plain text", what is an easy/reliable/secure method to insert data into the page (in a span) with correct escaping?

As per above, it should run in the context of a data-bound control. I am aware of HttpUtility.HtmlEncode, but I would like to entertain the idea of still using a control - perhaps there is a standard control for this task that I missed - to represent this case safely, without the need for wrapping the Eval. If this is misguided, based on logic or experience, it would be good to include in replies. I would not reject the notion that my use of Label in this case is entirely inappropriate.

Unfortunately, due to needing to run in a SharePoint 2010 context, I target ASP.NET for .NET 3.5, and not ASP.NET 4.

Community
  • 1
  • 1

3 Answers3

5

What about:

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

This escapes the output of the eval, this only works in .NET 4.

For .NET 3.5 a solution can be:

CodeBehind:

public object EvalEncode(object container, string expression)
{
  string ouput = DataBinder.Eval(container, expression).ToString();
  return HttpUtility.HtmlEncode(ouput);
}

MarkUp:

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

Instead of using HttpUtility.HtmlEncode, it's maybe better to use the AntiXSS library. For .NET 4 users it's already backed into the framework.

Erwin
  • 4,757
  • 3
  • 31
  • 41
  • Is there a link/reference for `<#:` in server tags to complete this answer? I can only find `<:` which is "like `<=` with escaping" as is new in ASP.NET 4 (I am unfortunately stuck with ASP.NET 3/3.5 whatever it is). –  Sep 06 '12 at 18:27
  • +1 Cool, that will be a really handy thing to know whenever I "move up". Unfortunately I am stuck in .NET 3.5 (I have included that information in the post now). –  Sep 06 '12 at 18:32
  • 2
    "Great minds think alike or fool .." :-) This is what I have just implemented (thankfully all my User Controls share a common base class, so it's easy), but slightly differently, I have a method `string HtmlEncode(object value)` so the call is `HtmlEncode(Eval("Text"))`. Explicitly having to use `Container.DataItem` doesn't sit well with me (if there was a way to access this in a *dynamically scoped fashion*, that would be really neat!) –  Sep 06 '12 at 18:57
  • 1
    This is like magic. Thanks. For those like me who had to laboriously compare the text, the difference in the .NET 4 line is a colon before the 'Eval'. – Resource Oct 02 '18 at 10:50
4

You could use an <asp:Literal ...></asp:Literal> control instead of the Label. The literal has a Mode property which you can use to tell the control to html encode its output.

Instead of this:

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

Try using:

<asp:Literal Text='<%# Eval("UserData") %>' Mode="Encode" runat="server"></asp:Literal>
Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
user1429080
  • 9,086
  • 4
  • 31
  • 54
  • +1 Ahh, very interesting to know! I did not know about the `Mode` option (I thought Literal was .. always Literal). It would have been nice if this property was also was present in a Label (for CssClass/wrapping span and other features) .. –  Sep 06 '12 at 19:45
  • @pst Well you could combine them since you can put the literal inside the label: `` instead of using the Text property on the label. – user1429080 Sep 06 '12 at 19:51
  • 2
    That's just getting more complicated than it's worth :) I was contemplating creating a "SafeLabel" control wrapper, but was hoping there was a standard "safe-Label" control. This does not seem to be the case, unfortunately. –  Sep 06 '12 at 20:09
0

Use the Microsoft Web Protection Library(Anti-XSS library) provided by microsoft for such purposes.

Security is hard, don't try to do it yourself. There is always be some hacker who is smarter.

You use it as follows:

<asp:Label Text='<%= Microsoft.Security.Application.AntiXss.HtmlEncode(Eval("UserData")) %>' runat="server" />
nunespascal
  • 17,584
  • 2
  • 43
  • 46
  • The comments (for the "1 stars") on that page scare me :( Have an example of how it (or the relevant part) would be used in this case? –  Sep 06 '12 at 18:29
  • You just need to call `HtmlEncode` before you render out any user data to the page. Doing this while you assign the text should be good. – nunespascal Sep 06 '12 at 18:41
  • I wonder what advantage it has over ``, unless HtmlUtility.HtmlEncode is not reliable .. I do not think I will use it (being another dependency), but +1 for the link which might help others needing the full library (and extra tool) support. –  Sep 06 '12 at 18:42
  • This is a lot stricter than `HtmlUtility.HtmlEncode`. It will check for html tags, script tags, css, in the text. – nunespascal Sep 06 '12 at 18:47
  • I only need to make sure that I can't introduce HTML tags in the output. It doesn't matter the tags are included in the content (e.g. I don't care about detecting malicious attempts), but they (the `<`s in particular) should be escaped accordingly. –  Sep 06 '12 at 18:50
  • (Oops, I've been calling it `HtmlUtility`, but the real namespace is `HttpUtility`.) –  Sep 06 '12 at 18:51