Wednesday, 6 February 2013

OWASP Top 10: #2 - Cross Site Scripting(XSS). How to prevent attack

This is one in a series of videos and blog posts that explore the top 10 most critical web application security risks as defined by OWASP.


In my previous session, I explained OWASP’s #2 from their top 10 web application security vulnerabilities. Cross Site Scripting(XSS).
 
We saw how easy it is for an attacker to exploit a vulnerable web application.

In this session, I’m going to show you several steps that can be employed to harden your application and mitigate against the threat of a Cross Site Scripting attack.
 

You can read the transcript below.

HTML5 player





Transcript








Let’s begin by loading the vulnerable site in Firefox.

I’ll use the search box on the front page to search for lager.

Let me attempt some HTML Cross Site Scripting by changing the query string parameter in the browser to SearchTerm=lager <em>yum</em> then pressing enter to load the page again.

As you can see, the page shows the word yum in italics thus confirming the markup itself has been manipulated.

OK. Let me launch Visual Studio 2012 and open the solution.

I want to open up the file Search.aspx.cs in the root of the project.

The first thing I need to do is add a using directive for the System.Web.Security.AntiXss namespace.

I can now use the AntiXssEncoder.HtmlEncode method to encode the searchTerm variable retrieved from the query string and set it as the Text property of the SearchTerm label.

That should do the trick. I’ll just build the project and then return to Firefox to reload the site.

Once again, I will use the search box on the front page to search for lager.

The results will be displayed without error.

Now let me try and repeat the attack that I tried earlier by changing the query string parameter in the browser to SearchTerm=lager <em>yum</em> then pressing enter to load the page again.

As you can see, the search results page loads with the search term lager <em>yum</em> rendered to the screen. In other words, the malicious script has been encoded safely.

Let’s look at a different technique. Whitelisting untrusted data.

I’ll return to Visual Studio 2012 to update the Search.aspx.cs file once again.

To begin with, I’ll add another using directive for System.Text.RegularExpressions.

On the line following that where I retrieve the searchTerm from the query string, I’ll create a regular expression to identify alphanumeric strings which may contain a space: @"^[0-9a-zA-Z ]+$". This should occur before the HTML encoding that I added earlier.

Now I need to match the untrusted data from the query string against the regular expression and throw an exception if it doesn’t match. This should also occur before the HTML encoding that I added earlier.

OK. Let’s see whitelisting in action.

I’ll just build the project and then return to Firefox to reload the site.

Once again, I will use the search box on the front page to search for lager.

The results will be displayed without error.

Now let me try and repeat the attack that I tried earlier by changing the query string parameter in the browser to SearchTerm=lager <em>yum</em> then pressing enter to load the page again.

Now we see an exception thrown.

This time, rather than accepting the malicious script and having to encode it before rendering, by whitelisting, we have prevented the script being entered in the first place.

Clearly, we need to tidy up the error page but I’ll leave that for another session.

 
Earlier, we encoded output for the HTML context. Now, I want to look at encoding for the JavaScript context.

Once again, I’ll switch back to Visual Studio 2012 and this time I’ll open the Product.aspx file in the root of the project.

In the JavaScript where the product variable is set, I’m going to replace the existing implementation and use the JavaScriptEncode method to encode the query string parameter. At the moment, the JavaScript code is simply rendering the content of the query string into a dialog.

It is important that I remove these quotes as the JavaScriptEncode method adds a pair of its own.

Time to save and return to Firefox to reload the site.

Once again, I will use the search box on the front page to search for lager.

In the search results, I’ll click on Laughing Lumberjack Lager.

The product page will load with a jQuery dialog box displaying the content of the ProductName query string parameter.

Let’s attempt some JavaScript XSS by changing the query string parameter in the browser to append code to update the hyperlink of the Login control to direct users to an evil site.

Unlike in the previous video where you saw the same attack result in the login control having its hyperlink updated, this time the malicious script has been safely encoded in the JavaScript context using the JavaScriptEncode method.

 
OK Let’s tackle another attack that we saw demonstrated in the previous video by enabling request validation.

Let me return to Visual Studio 2012 and open up the web.config file.

I’ll locate the pages node and set the validateRequest attribute to true.

This option tells ASPNET to prevent any suspect content being entered into form fields.

Time to save the Web.config file and return to Firefox to reload the page/site.

As before, I’ll enter lager <em>yum</em> into the search box on the front page.

But this time, I receive an error of type HttpRequestValidationException.
 

OK. We have seen a number of ways in which malicious script can be prevented from entering the system or reflected safely.

But what about persistent Cross Site Script? i.e. What if the untrusted data is already in the system? What if it entered previously and is sitting in the database waiting to be retrieved?

Let me reload the home page in Firefox.

 
This time I am going to search for ale.

When the page loads, an alert box is displayed with the text XSS.

Let’s take a look at the source for this.

Let me find the entry for the second result.

Look at how the href property of the hyperlink has encoded open angle brackets and quotes whereas the contents of the tag has no encoding.

That content has come from elsewhere in the system.

Let’s take a look in the database.

I’ll open SQL Server Management Studio 2012 and begin a new query.

I need to set the query context to the appropriate database so that I can write a query to retrieve records from the Products table that contain data like ale.

OK. So I’ll execute this query.

And sure enough, we can confirm the existence of a persistent XSS risk by observing the script tag found in the ProductName column of the product record with an ID 34.

So let’s mitigate against persistent Cross Site Script.

I’ll switch back to Visual Studio 2012 and open the Search.aspx file

I’m going to add an OnRowDataBound event handler to the GridView control called SearchGrid_RowDataBound.

Notice how the first column of the GridView is a HyperLinkField.

I’ll open the Search.aspx.cs file once to find the event handler stub created by Visual Studio 2012 waiting for me.

In the event handler, I’ll test to see if the row type being bound is not a DataControlRowType of type DataRow. If it isn’t, I’ll return from the method.

 
The next thing to do here is to locate the HyperLink control in the first column of the row and use AntiXssEncoder.HtmlEncode to encode the existing Text value of the control.


OK time to build the project and return to Firefox for one last test.

Once again, I’ll search for ale.


But this time, look at how the persistent Cross Site Script has been safely encoded.


So there you have it. We have looked at a number of approaches in this session. From encoding output for both the HTML and JavaScript contexts, whitelisting untrusted data, enabling request validation, and protecting against persistent data. No single approach will mitigate against the threat of Cross Site Scripting - XSS on its own. Rather it’s a combination of these things or layers.

In this session we have seen how simple it is to mitigate against the threat of Cross Site Scripting - XSS. The #2 in OWASPs top 10 web application security vulnerabilities.



Flash player



Training?

If you are interested in OWASP training, we offer the following courses:




See you soon

Phil Stirpé
"I don't do average!"





No comments:

Post a Comment