3
votes

I created a simple .NET web form application which runs on .NET 4.7.2.

This application has a text box, a submit button and a label. When you click on the submit button the application displays the text box content.

enter image description here

To make this application vulnerable to Cross site scripting, I disable the request validation (validateRequest=false) in its web.config. This allows me to type in the text field the value: XSS<img src=x onerror=confirm("HACKED")> and submit.

enter image description here

Upon clicking Submit I see the pop up

enter image description here

In order to prevent XSS attack, I went and got the NUGet package for AntiXss library and reference it in my web.config as per the instruction from Microsoft AntiXss document.

enter image description here

However, nothing encoded and my web app still vulnerable to XSS attack until I explicitly encode the value in my code.

        protected void Button1_Click(object sender, EventArgs e)
        {
            //Label1.Text = TextBox1.Text;
            Label1.Text = AntiXssEncoder.HtmlEncode(TextBox1.Text,true);

        }

With the value encoded using AntiXss library, the application now displays the value instead of executing that script and creates the pop up.

enter image description here

So I have three questions:

  1. What does the web.config encoderType="System.Web.Security.AntiXss.AntiXssEncoder" really do because it does not change my test result wether I put it in or remove it out of my web.config. According to Micrsoft document, this sets the default handler for HTML and URL encoding tasks.
  2. If I have to encode each and every text fields to prevent XSS attack, is there a site wide approach to encode all of its fields? it does not seem like a practical solution for a site (not MVC) that has hundred of pages with numerous input field spread out all over the place and having to HTMLEncode one by one.
  3. How does validateRequest work with XSS prevention other than display that standard .NET detect dangerous request page? Can I catch it as exception and display an error message on my page instead of display the default error page like the one below.
1

1 Answers

2
votes

Ok so first, starting with .Net 4.5, (most of) the AntiXSS library is part of the framework itself, it is in System.Web.Security.AntiXss, you don't need to provide the dll separately.

By default, the framework html encodes output when written from Razor with @, or from asp.net with <%: (instead of <%=). What this does is html encoding, and .Net does this by default with it's previous, blacklist based method, which has a list of characters to encode (like eg. < and so on), and leaves alone the rest. That is ok for many usecases, but switching to AntiXss with encoderType="System.Web.Security.AntiXss.AntiXssEncoder" enables a whitelist based encoder, which means it has a list of "harmless" characters like letters and numbers, and encodes everything else, which makes it more secure in more scenarios.

Note a few things though.

  • AntiXSS as included in the framework does not support the html sanitizing features previously present in the AntiXSS library. You usually don't need that, the usecase for that is when you delibertaely have html user input which you also want to display as html (like for example a rich text editor on the web ui), and even then the method in AntiXss was not very robust and secure for the purpose, I guess that's why it was left out.
  • Different contexts need different encoding. In a html context (between html tags) just using @myVar in Razor or <%: myVar %> in asp is fine, and will be correctly encoded. It will mostly be ok for html attributes too, but in an attribute you might want to use the specific attribute encoding method AntiXssEncoder.HtmlAttributeEncode. For Javascript (in a script tag, or in event attributes like on*), you need JavascriptEncode, and even that is only secure if used in quoted strings (that's why by default it adds the quotes).
  • Request validation does not prevent xss in general. It does prevent some basic attack vectors, but many are left untouched by request validation and you have to take care of those by hand (especially, but not exclusively the javascript related ones).

So in short, there is no magic bullet against XSS. You cannot just fix it in one place and forget about it, if that was possible, the framework would probably already do that. You need to apply the correct encoding in each and every place where user input makes it into a page. The only help is that if you use the correct output methods (@ and <%:), basic html encoding is applied automatically, but as discussed above, that does not work for javascript, and certain other scenarios (for example writing a user provided url in a link will likely result in a user being able to provide javascript:alert(1) - and no encoding will remove this, which is just nasty).

Based on this, to answer your explicit questions:

  1. The standard encoded output tags (@ and <%:) apply basic html encoding. Whether this is the older standard blacklist based, or the more secure whitelist based depends on whether you select the AntiXss encoder, already in the framework.
  2. No, but there is some help if you use the correct tags. But in general you have to review each and every variable output.
  3. All validaterequest does is it looks for a less than character directly followed by a letter in any user input (url variable or form field, but not for example cookie values and request headers, which also might become attack vectors). You should not really rely on that too much. Unfortunately I don't know how you can display a custom error page (it's been a while since I did .Net), but I'm pretty sure it's possible. :)