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.
-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.
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" %>
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:
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.
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;
}
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.