Reputation:
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.
Upvotes: 7
Views: 10240
Reputation: 9166
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>
Upvotes: 4
Reputation: 4817
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.
Upvotes: 5
Reputation: 17724
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" />
Upvotes: 0