Take Charge of Your Security

asp.net mvc, asp.net, code 0 comments suggest edit

Today I read something where someone was comparing Web Forms to ASP.NET MVC and suggested that Web Forms does a lot more than ASP.NET MVC to protect your site from malicious attacks.

One example cited was that Server controls automatically handled HTML encoding so you don’t have to really think about it. The idea here is that Web Forms automatically protects you from XSS attacks.

My friends, I’m afraid this is just not true. Take a look at the following page code.

<%@ Page Language="C#" Inherits="System.Web.UI.Page" %>
<%
//For demo purposes, we have inline code here.
// Pretend the following userInput came from the database
string userInput = "<script>alert('You’ve been Haacked!');</script>";
label1.Text = userInput;
literal1.Text = userInput;
%>

<html>
<head>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Label ID="label1" runat="server" />
        <asp:Literal ID="literal1" runat="server" />
    </div>
    </form>
</body>
</html>

In this page, we simulate taking some some user input we got from somewhere, whether it’s from a form post or from a database, and we place it in a Label control, and in a Literal control.

These are two of the most common controls used to display user input. I’ll save you the suspense of having to actually try it out, and just show you what happens when run this page.

Message from
webpage

Contrary to popular belief, these controls do not automatically HTML encode their output. I don’t see this as some gaping security flaw because it may well be that the intention of these controls, and general usage, is to display HTML markup the developer specifies, not what the user specifies. The potential security flaw lies in using these controls without understanding what they actually do.

The lesson here is that you always have to think about security. There’s no silver bullet. There’s no panacea. Damien Guard has a great post where he lists other signs your ASP.NET application might be succeptible to injection attacks, pointing out various ways that protection is not automatic.

The best approach is to take a more holistic approach. Create a threat model for your website and start attacking your own site as if you were a hacker, looking for flaws. Conduct security reviews and use any automated tools you can find for finding potential flaws. I recommend taking a look at CAT.NET combined with the AntiXss library.

In this particular case, I don’t think Web Forms provides any more automatic security than ASP.NET MVC. With MVC, we’ve swapped server controls with our helper methods, which properly encode output. If you don’t use our helpers, it’s roughly equivalent to not using the server controls.

Interestingly enough, in order to get that particular user input to the page in the first place is tricky. If you were to create a Web Form with a text input and a button, and type that script tag into text box and click the button, you’d be greeted by the following yellow screen of death.

request-validation

By default, ASP.NET has Request Validation turned on, which prevents requests with suspicious looking data such as the one I tried. Note that ASP.NET MVC also has Request Validation turned on by default too. You can turn it off per Controller or Action via the ValidateRequestAttribute like so.

[ValidateInput(false)]
public ActionResult SomeAction(string someInput) {
}

This is not to say that I think ASP.NET MVC provides just as much automatic protection that Web Forms does. This is not exactly the case. There are some cases where Web Forms does provide more automatic protection that ASP.NET MVC leaves to you, the developer.

For example, ASP.NET MVC does not have an automatic equivalent of Event Validation which was introduced in ASP.NET 2.0. Note that event validation is very different from request validation and is very specific in to server controls. For example, as the blog post I linked to mentions, if you add a DropDownList control with three options, and a user posts a non-existent option, you will get an exception. ASP.NET MVC doesn’t have such automatic validation. In some cases, this is a good thing because it makes AJAX scenarios simpler.

What ASP.NET MVC does have is a set of Anti Forgery (CSRF) helpers which require a bit of manual intervention.

To recap, while I do agree that Web Forms does provide a bit more automatic security than ASP.NET MVC, the gap is not as wide as you might think. Server controls are no more nor less secure than using the Helpers with ASP.NET MVC. And all of that is irrelevant because it is still up to the developer’s to take responsibility for the security of his or her site. I’ve heard of many developers who had to turn off Request and Event Validation for various reasons. In those cases, they examined the attack vectors opened up by these changes and provided alternate protections to replace the ones they turned off.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

22 responses

  1. Avatar for Kazi Manzur Rashid
    Kazi Manzur Rashid February 7th, 2009

    Yes, I felt into the same trap after upgrading into RC1, did not find it mentioned both you and ScottGu's post. In my case I was accepting few known html tags.
    Another interesting this is it not only implemented for Form but also for QueryStrings.

  2. Avatar for Paul
    Paul February 7th, 2009

    In my experience, when request validation is disabled, it is at some point after the start of the project. If built-in control validation was the only form of security, you end up having to go back through your forms to tighten up the input. This is obviously an error-prone exercise.

  3. Avatar for Josh Carroll
    Josh Carroll February 7th, 2009

    I worked a project once where we hired some contractors. He was having some problems with ASP.Net Form validators not quite working the way he expected. Turns out he had no idea about the whole Page.IsValid property. When I told him about it, he was like "Wow, I have been doing this wrong for a while now!"
    Indeed...

  4. Avatar for Damien Guard
    Damien Guard February 7th, 2009

    There's a whole host of missing encodings in the WebForms model, I detailed a few at damieng.com/.../5-signs-your-aspnet-application...
    [)amien

  5. Avatar for Dominic Pettifer
    Dominic Pettifer February 7th, 2009

    Some ASP.NET WebForm controls DO perform automatic HTML encoding to prevent XSS attacks, while some will only encode certain properties. Specifically the TextBox control's Text property, and the NavigateUrl property of the HyperLink control but NOT the HyperLink's Text property. Also I believe the ListItem Text and Value fields used in DropDowns and Radio/Checkbox lists perform auto HTML encoding. It's always worth finding out which controls and their properties do and don't perform this encoding, as you do want to prevent XSS but don't want to encode the HTML output twice or you'll get funny output.
    What I want to know is, has this behaviour been carried over to MVC, for instance if I set the value attribute of an <input type="text" with the Helpers, will this be automatically HTML encoded?

  6. Avatar for Steve Sheldon
    Steve Sheldon February 7th, 2009

    Ok... So what is Microsoft's recommended solution when you wish to allow users to enter some selected HTML tags?
    The AntiXSS library is helpful for a small subset of problems. The reason why most XSS occurs though is because we want to allow users to enter some markup. But what if a user wants to bold a word? The AntiXSS library just encodes it.

  7. Avatar for haacked
    haacked February 7th, 2009

    @Steve That is exactly a shortcoming of our current libraries. This is something I hope to address at some point in time.

  8. Avatar for Steve Sheldon
    Steve Sheldon February 7th, 2009

    @haacked: I think that would be extremely helpful. Thanks

  9. Avatar for Jahedur Rahman
    Jahedur Rahman February 7th, 2009

    Well, I agree with you. Actually security issues should be let to be handled by developers not by the language itself.

  10. Avatar for Jeff Ancel
    Jeff Ancel February 7th, 2009

    <3 ASP.NET MVC. Hate security issues, but when there are 1 billion (that's a wild guess) potential customers, it is something that is necessary.

  11. Avatar for barryd
    barryd February 7th, 2009

    Taking some inspiration from the MVC CSRF protection (and as a book topic as well) I ended up with <a href="http://anticsrf.codeplex.com>AntiCSRF for ASP.NET.
    It's not exactly the same, it's opt-out rather than opt-in but but it should automatically add and check CSRF tokens/canaries to your webforms pages.

  12. Avatar for Stanley Colpas
    Stanley Colpas February 7th, 2009

    ASP.NET MVC is great, but unfortunately its default templating system is not so great. For example, the following is very common:
    <div><%= name %></div>
    The contents of the name variable might be coming from the database, and when the contents were inserted into the db the original content may have come from a form input, i.e. input from the user. So the contents of name cannot be trusted (no, the request validation cannot catch everything).
    The official way to do things like this is to always use Html.Encode(name) but I think that's just plain wrong. Why to default NOT to encode? I'd say that it's an exception, not a rule, to want input like that not being encoded.
    Luckily there exists a great alternative to the default templating system. The alternative is called Spark. In Spark it's possible to set AutomaticEncoding to true, after which normal ${name} is automatically encoded, and if the developer specifically wants to not encode the output, it's as simple as this: !{name}.
    I like ASP.NET MVC quite a lot, but you developers should focus on safe default work flow. No wonder the net is full of sites vulnerable to XSS when framework defaults are usually unsafe.

  13. Avatar for Rob
    Rob February 7th, 2009

    Phill,
    Whoever you were quoting, was obviously not talking about the literal control (and probably should have specified), but some of the web controls DO encode.
    Dim gv As New GridView
    Me.form1.Controls.Add(gv)
    Dim lst() As String = {"[insert javascript alert here]", "test"}
    gv.DataSource = lst
    gv.DataBind()

  14. Avatar for haacked
    haacked February 8th, 2009

    @Rob true, some of them do. But my point is that it's not automatic. Some that you might expect to encode, don't. See the link to Damien Guard's post I linked to for other examples.

  15. Avatar for barryd
    barryd February 8th, 2009

    Assuming I can get the a tag right this time Sascha Faust has a good list of what properties get encoded or not in webforms controls.

  16. Avatar for Coder
    Coder February 8th, 2009

    I like that you have to turn off request validation. At least it makes you think about output encoding.

  17. Avatar for benb
    benb February 8th, 2009

    Phil, thank you for the update, as I thought this may have been an issue with the following type of url: http://localhost:2368/search/%22tomato%20paste%22
    However, it seems this is a shortcoming of the MVC handling as there is no way to override the error which ultimately fails because it is trying to map the "tomato paste" to a physical file.
    [ArgumentException: Illegal characters in path.]
    System.IO.Path.CheckInvalidPathChars(String path) +7491909
    System.IO.Path.Combine(String path1, String path2) +40
    System.Web.Configuration.UserMapPath.GetPhysicalPathForPath(String path, VirtualDirectoryMapping mapping) +114
    This has been submitted for months as an issue on codeplex - is there a plan to fix this, as certainly it should be acceptable to have input that is not a valid Windows file name?
    Thank you for any input you can give, as this makes some scenerios not workable. Including some put up by ScottGu for search.

  18. Avatar for Lee Timmins
    Lee Timmins February 8th, 2009

    Here's a run down of asp.net web forms encoding:
    msmvps.com/.../...-with-asp-net-html-encoding.aspx
    Also i believe it would be great if there was a setting to automatically encode. Therefore <%= would encode automatically but to allow html you would put <%!= (or something similar). While it would not solve every problem it would certainly help those that are unaware of a potential vulnerability or forget to encode to their data.

  19. Avatar for Filini
    Filini February 8th, 2009

    Starting from Steve's question, I think there are two very different scenarios for letting the user input some markup:
    1. The user wants to format what he's writing. I would solve this problem avoiding HTML at all, and using an alternate markup (BBCode, or else)
    2. The user wants to show some Code, specifically, HTML or Javascript. This is the scenario that should be deeply covered in guidelines and patterns.

  20. Avatar for Keen
    Keen February 9th, 2009

    I agree with you. Actually security issues should be let to be handled by developers not by the language itself. I agree too

  21. Avatar for Jessica
    Jessica February 12th, 2009

    I think it's just a matter of developers getting their act together. Too many developers write sloppy code that doesn't check for error conditions, or do input validation.
    Letting the framework play it safe for you just encourages more sloppy coding in my opinion.

  22. Avatar for shree
    shree June 1st, 2011

    CAT.NET no longer available for VS2010..The Released Beta was also revoked and never came back...what you suggest???