Evil I/O: MS AntiXSS & Preventing XSS Attacks

With the recent release of the Microsoft Anti-Cross Site Scripting (AntiXSS) Library V3.0 Beta, I decided to take the opportunity to yet again remind everyone how important security is, in particular, prevention of XSS (Cross Site Scripting) attacks.

XSS attacks are disturbingly common. Take for example, stats from the Internet Security Threat Report published in April of 2008. During the second half of 2007, 11,253 site-specific cross-site vulnerabilities were documented, compared to 2,134 traditional/other type vulnerabilities documented by Symantec in this report. That’s a huge number of sites affected, and you could easily be a target by both web surfing and worse, by developing unsecured applications you can be inadvertently contributing to attacks on others.

As a consultant, I can say that out in the real world I can barely go a few weeks where I don’t see gaping security holes in various applications. This happens even though many of the more security conscious clientele of mine hire ethical hackers to come in and poke holes in their apps so they can then strengthen them. The clients who aren’t security conscious end up with sites that are horrendous security-wise, and it shows that they were developed without the least bit of thought about preventing intrusion and locking down assets.

So What is XSS Anyway?

XSS is an injection attack so this works in a similar fashion as SQL injection, but that’s as far as the analogy goes since the target is different (it’s not the db), and so are the consequences. During an XSS attack the attacker will inject JavaScript, VBScript, ActiveX controls, Flash or HTML into a web page that’s been dynamically created. The malicious payload is then directed to an unsuspecting user of your application, and the attacker can then read cookies, collect user names & passwords, redirect the victim to a spoof site or more. If the user has elevated privileges in your application, the attacker can then try to run under that user’s context, putting both your environment and your users at risk. XSS attacks are all about input and output – if an attacker spots a vulnerable web site that doesn’t properly deal with input, s/he will send malscripts to that unprotected web site to do harm. I can only get into basics of XSS here but details on the mechanics of XSS attacks can be found at WASC and CGI Security. IBM has some great sample XSS attack scenarios as well.

It’s All About The I/O

As with any security strategy, the key is to reduce the attack surface. A few tasks you should add to your development efforts that will help reduce the attack surface for XSS attacks:

  • Sanitize Input
  • Sanitize Output
  • Encode Output

This might not sound like a lot of work to do, but it ends up being a very tedious task making sure every single source of input and output has been sanitized. The input sources range from form fields, URL query strings, HTML attributes (yes HTML attributes), DOM elements, cookies and data to any piece of information in your site. Most developers apply a filter using Regular Expressions, however this won’t work well if you consider that you would need to apply a regex filter to each and every piece of data that comes into your app and you’ll need to filter for every possible harmful script, action or attribute.  Some developers build custom libraries to handle the task, and although this is better than nothing, it’s very easy to miss many of the potential malicious tokens that reach your site.

An easier approach rather than manually filtering is to take a whitelist approach to input sanitization. Rather than accept all input first and then try to figure out what’s not acceptable, you flip the input paradigm and don’t allow any input, except designated pieces or patterns of data. For example if you whitelist just plain text, then the only input allowed is A-Z & 0-9; no HTML tags, no special characters, or anything else is allowed. This makes dealing with any volume of input much easier, and more effective as you now know nothing’s been forgotten.

Enter AntiXSS Library

The AntiXSS library is an encoding library that uses a whitelist approach for you to work with. Once you’ve downloaded the library and run the installer you can add a reference to the AntiXSSLibrary.dll and AntiXSSModule.dll files. This gives you programmatic access to the encoding utilities and you can start using the library immediately. Below is a sample of URL and HTML encoding :

using Microsoft.Security.Application;
protected void loginButton_Click(object sender, EventArgs e)
{
    //run of the mill forms authentication code
    if (FormsAuthentication.Authenticate(userName.Text, password.Text))
    {                
        FormsAuthentication.SetAuthCookie(userName.Text, false);                
        Response.Cookies["UserSettings"]["Username"] = userName.Text;
       
        if (Request.QueryString["RedirectUrl"] != null)
        {
            //Encoding the QueryString value
            //AntiXss.UrlEncode is being used as the data is being passed
            //as a URL to Response.Redirect
            string tempUrl = AntiXss.UrlEncode(Request.QueryString["RedirectUrl"]);
            Response.Redirect(tempUrl);
        }
        else
            Response.Redirect("default.aspx");
    }
    else
    {
        errorLabel.Text = ("Invalid user name or password");
    }
}

protected void setLabelData()
{
    //Data being encoded using HtmlEncode as the Label.Text
    //places data directly inside HTML elements.
    locationLabel.Text = AntiXss.HtmlEncode(Request.QueryString["location"]);
}

You can tap into methods for encoding JavaScript, VBScript, HTMLAttributes and XML Elements and attributes as well. And as you can see, there’s no huge difference in your day to day coding tasks here – the code is standard C#, VB.NET or whatever you choose. That makes the library easy to use, so now you have no excuses. If you were already using HttpUtility.HTMLEncde, this code should be very familiar, which leads to the next point…

What About HttpUtility.HTMLEncode?

If you were using the .NET Framework System.Web.HttpUtility.HtmlEncode and related methods, it’s no problem, the AntiXSS library isn’t meant to replace them completely, and it doesn’t mean that there are problems or bugs in the HttpUtility’s HtmlEncode method. The difference between the two encoding methods is that the AntiXSS library uses a whitelist and anything outside the whitelist is automatically encoded. You need to programmatically define which input and output to encode using HttpUtility’s HtmlEncode. In short, the AntiXSS library should save you a lot of time because you don’t need to create your own code to figure it all out.

Summary

Recently popular sites like Google, Facebook[*] and Citibank (links go to explanations of the exploits, not the sites) have had recent exploits as described here at XSSED.com.  Considering that many people use the same password for multiple sites, if an attacker gets your password, they can try easy combinations of your name as a user name to get into banking or other sites that deal with your personal information. Scary!

Remember all input is evil, always. And Output, Input’s little brother, isn’t all that nice either.

[*] I have had two friends that have recently been hit with the latest XSS attack on Facebook.