Wednesday 18 September 2013

Absolute Beginner's Tutorial on Cross Site Scripting (XSS) Prevention in ASP.NET

In our last post we saw Trick to download facebook Photo Album-Link in this post we will see what is Cross Site Scripting(XSS). We will try to see some samples that are vulnerable to XSS and try to inject some scripts. We will then see how we can prevent XSS attacks in an ASP.NET website. Cross Site scripting is one of the problem that has plagued a lot of websites. According to WhiteHat Security Top Ten more than 50% of the websites are vulnerable to cross site scripting. As a web developer, it is important to understand what is cross site scripting and how can we safeguard our site from such attacks.

Cross site scripting is nothing but injection of client side scripts into a website. These scripts can be HTML scripts or JavaScript scripts. Now the question would be how can a person inject scripts on a running page. This can easily be done using all the various ways a website is collecting inputs. Cross site scripting can be performed by passing scripts in form of:

-TextBox (input controls)
-Query Strings
-Cookies
-Session variables
-Application variables
-Retrieved data from an external or shared source

Now let us see some very rudimentary example of cross site scripting and then we will try to see what ASP.NET provides to prevent cross site scripting. We will also look at the best practices that needs to be followed in order to make our website safe from cross site scripting attacks.

Now before writing applications that are vulnerable to cross site scripting we should know that ASP.NET provides some security out of the box against such attacks i.e. RequestValidations. This is a good thing for an ASP.NET developer. We will talk about it in the later part of the article but for now lets us see how can we disable this prevention mechanism.


Getting your Test Project Ready

The first thing that we need to do to disable the request validations is to set the ValidateRequest property of the page directive to false. If we need to do this for the whole website then we can do this from the web.config pages element.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" ValidateRequest="false" %>


Now, in order for the above setting to work we also need to change the requestValidationMode of the http Runtime to 2.0. The request validation will only be turned off when this mode is set to 2.0 otherwise it will not work.

<httpRuntime requestValidationMode="2.0"/>


We are disabling the request validation because we want to test the cross site scripting. without disabling it wont be possible to see cross site scripting in action. It is not recommended to turn off requestvalidation in production environment because this will open the website for cross site scripting attacks.


Perform XSS using Query Strings

Now let us create a simple web form that will simply accept a query string from the user and display the query string values on page.




The code behind this page looks like this: protected void Page_Load(object sender, EventArgs e)

{

      string id = Request.QueryString["id"] as string;

  

      if (id == null)

      

      {

               lblId.Text = "NA";

      }

      

      else 

      

      { 

      

               lblId.Text = id;



      }

}


Now under normal circumstances this will work just fine but if we try to pass some script in the query string variable then we have a problem. Let me now pass the query string parameter as:

Default.aspx?id=<h3>Hello from XSS"</h3>


and now when we open the page






And now herein lays the problem. The user can pass any HTML from the query string and that HTML will be rendered on the page. This was a very basic example but imagine an HTML with absolutely positioned tags and images could possibly wipe out the original page and show something else entirely.

Same thing can happen with JavaScript too. I can inject any javascript into this page. Let us try this:

Default.aspx?id=<script>alert('you have been hacked');</script>

and the output will be:





Preventing Cross Site Scripting:

ASP.NET websites developers have some advantages over other technologies because ASP.NET has some cross site scripting prevention logic baked into the framework itself i.e. RequestValidations. In our earlier examples we disabled it to check the cross site scripting but it is not at all recommended and should not be disabled unless it is a must.

If we enable the page with RequestValidation as true then we will get an error rather than modified page.






But apart from this in built default prevention mechanism developer should always follow the following guidelines to prevent XSS.

1. Constrain the user input to the characters that are acceptable for that particular field.
2. Never trust user input. Always encode all the user inputs before processing them.
3. If data is coming from an external source or a shared source, never show raw data. Always encode the data before displaying it to the user.

Now let us go back to our XSS prone page again. We will add one more textbox and button on the page to see how we can constrain user input.

We can always use JavaScript filters to constrain the user input. Let us apply some javascript based filters on this new text box so that we will only accept alpha numeric characters and noting else.


<asp:TextBox ID="TextBox2" runat="server" onkeypress="return AcceptAlphaNumericOnly(event, false, false);"></asp:TextBox>

Now this will prevent the user from typing any unwanted characters in the textbox. We should also check for and remove the unwanted characters on server side too because client side scripts can be bypassed easily(even in the above text box we can paste the copied scripts).

Now as for the encoding the user input part. Let us add a similar textbox again and put the the logic for encoding the user input in for this.


protected void lblMessage3.Text = "Hello " + encodedinput; Button3_Click(object sender, EventArgs e)



{

           string rawInput = TextBox3.Text; 

           string encodedinput = Server.HtmlEncode(rawInput);

       lblMessage3.Text = "Hello " + encodedinput;

}

Now if we try to inject something in using this textbox, the output will be:




Same should be done if the data is coming from an external or shared source. We should never trust the data that is not created by us.

So now we know some basic prevention mechanism that could prevent our site from cross site scripting. Along with these mechanism, use of some stable third party cross site scripting protection library is also advisable. One such library is AntiXSS (http://wpl.codeplex.com/). Use of such libraries will provide the prevention in conditions where the framework and framework functions are falling short.









0 comments:

Post a Comment

 

Subscribe to our Newsletter

Contact our Support

Email : ajai199@gmail.com