Using AntiXss As The Default Encoder For ASP.NET

asp.net mvc, asp.net, code 0 comments suggest edit

This is the third in a three part series related to HTML encoding blocks, aka the <%: ... %> syntax.

Scott Guthrie recently wrote about the new <%: %> syntax for HTML encoding output in ASP.NET 4. I also covered the topic of HTML encoding code nuggets in the past as well providing some insight into our design choices for the approach we took.

A commenter to Scott’s blog post asked,

Will it be possible to extend this so that is uses libraries like AntiXSS instead? See: http://antixss.codeplex.com/

The answer is yes!

ASP.NET 4 includes a new extensibility point which allows you to replace the default encoding logic with your own anywhere ASP.NET does encoding.

All it requires is to write a class which derives from System.Web.Util.HttpEncoder and register that class in Web.config via the encoderType attribute of the httpRuntime element.

Walkthrough

In the following section, I’ll walk you through setting this up. First, you’re going to need to download the AntiXSS library which is at version 3.1 at the time of this writing. On my machine, that dropped the AntiXSSLibrary.dll file at the following location: C:\Program Files (x86)\Microsoft Information Security\Microsoft Anti-Cross Site Scripting Library v3.1\Library

Create a new ASP.NET MVC application (note, this works for *any* ASP.NET application). Copy the assembly into the project directory somewhere where you’ll be able to find it. I typically have a “lib” folder or a “Dependencies” folder for this purpose. Right clicke on the References node of the project to add a reference to the assembly.

add-reference Add-Reference-dialogThe next step is to write a class that derives from HttpEncoder. Note that in the following listing, some methods were excluded which are included in the project.

using System;
using System.IO;
using System.Web.Util;
using Microsoft.Security.Application;

/// <summary>
/// Summary description for AntiXss
/// </summary>
public class AntiXssEncoder : HttpEncoder
{
  public AntiXssEncoder() { }

  protected override void HtmlEncode(string value, TextWriter output)
  {
    output.Write(AntiXss.HtmlEncode(value));
  }

  protected override void HtmlAttributeEncode(string value, TextWriter output)
  {
    output.Write(AntiXss.HtmlAttributeEncode(value));
  }

  protected override void HtmlDecode(string value, TextWriter output)
  {
      base.HtmlDecode(value, output);
  }

  // Some code omitted but included in the sample
}

Finally, register the type in web.config.

...
  <system.web>
    <httpRuntime encoderType="AntiXssEncoder, AssemblyName"/>
...

Note that you’ll need to replace AssemblyName with the actual name of your assembly. Also, in the sample included with this blog post, AntiXssEncoder is not in any namespace. If you put your encoder in a namespace, you’ll need to make sure to provide the fully qualified type name.

To prove that this is working, run the project in the debugger and set a breakpoint in the encoding method.

debugger-breakpoint

With that, you are all set to take full control over how strings are encoded in your application.

Note that Scott Hanselman and I gave a live demonstration of setting this up at Mix 10 this year as part of our security talk if you’re interested in watching it.

As usual, I’ve provided a sample ASP.NET MVC 2 project for Visual Studio 2010 which you can look at to see this in action.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

24 responses

  1. Avatar for James Alexander
    James Alexander April 5th, 2010

    Super hawt

  2. Avatar for Andrew
    Andrew April 5th, 2010

    Phil-
    Looks great. I do wonder what the main difference between using MS default encoder vs a 3rd party library such as AntiXSS?

  3. Avatar for DonSleza4e
    DonSleza4e April 5th, 2010

    Awesome
    Integrated lib with my asp.net mvc project ^^

  4. Avatar for schneitj
    schneitj April 5th, 2010

    What is the counter argument to this? Why isn't it the default encoder already? Performance?

  5. Avatar for Ryan Smith
    Ryan Smith April 5th, 2010

    @schneitj
    My guess is because if you are migrating from a previous version, if it's the default then you'd be double encoding.

  6. Avatar for Barry Dorrans
    Barry Dorrans April 5th, 2010

    Heh. So as the lead developer on AntiXSS/WPL I can say that the next public release will have its own class for this. Actually, it'll have its own assembly for this, as it's a NET 4.0 only function.
    The main difference between the two sets of encoders is the approach. The .NET encoder uses a small blacklist for its encoding, AntiXSS uses a large whitelist. While this is safer it does have a performance cost which some folks may find hard to swallow. We publish performance states for the WPL, but I don't think we've ever published stats for the raw encoders - I'll take a look at doing that.
    Note that you don't need to use the WPL to use AntiXSS - you can manually encode to your heart's content and the next release will separate out the encoding classes into their own assembly again.

  7. Avatar for Paul
    Paul April 6th, 2010

    Nice post! Is this for people planning to stay on .NET 3.5 or lower, giving them proper encoding when they use <%=%> ??? Or is this some how better then the new <%:%> in .NET 4.0?

  8. Avatar for David Keaveny
    David Keaveny April 6th, 2010

    This is beyond awesome. It's bey-awesome!

  9. Avatar for Harvey Kandola
    Harvey Kandola April 6th, 2010

    Heads-up: AntiXSS does not work on Medium Trust.

  10. Avatar for Dhananjay Goyani
    Dhananjay Goyani April 6th, 2010

    Good question Andrew.
    Phil, Barry,
    If AntiXss is more mature then I wonder why not to make it first class citizen in ASP.NET itself.

  11. Avatar for Barry Dorrans
    Barry Dorrans April 6th, 2010

    Harvey you're correct, the current version doesn't. The next version will - well, the encoding bits will, HTML santisation will still require full trust I'm afraid.
    Dhananjay that conversation has been started, but it's not one I've been involved with - I only started at MS 8 weeks ago!

  12. Avatar for haacked
    haacked April 6th, 2010

    Hi all, regarding why AntiXss isn't the default encoding. This may be something that may happen in the future, but there are several issues that need to be addressed first such as the Medium Trust issue.
    Our team and there team do communicate with each other. It's obviously too late for ASP.NET 4, but could perhaps make it in a future version, which gives us time to make sure it's ready to be included if we choose that route.

  13. Avatar for Dhananjay Goyani
    Dhananjay Goyani April 7th, 2010

    I understand. On an other note, I expect same treatment for MS Ajax Minifier.

  14. Avatar for Daoming
    Daoming April 13th, 2010

    Hi Phil, would be be able to check the following link about file not found exception in MVC?
    http://stackoverflow.com/questions/2641526
    Many thanks.

  15. Avatar for Harvey Kandola
    Harvey Kandola April 16th, 2010

    @Barry thanks for the medium trust support: we recently ended up ripping out the vast majority of the codebase and just used the string encoding bits (I think there was a lot of file/IO stuff that caused us issues).
    Looking forward to the next release.

  16. Avatar for handcode
    handcode April 27th, 2010

    Hi Phil,
    What is the difference between AntiXss.HtmlEncode and HttpUtility.HtmlEncode?

  17. Avatar for SarahBrooks
    SarahBrooks May 2nd, 2010

    Hi Phil,
    The SampleApp that comes with the AntiXSS download targets the .NET 2.0 framework. The solution compiles in VS2008, but not in VS2010.
    www.microsoft.com/.../details.aspx
    Is AntiXSS referenced in projects targeting .NET 2.0 supported in VS2010?

  18. Avatar for Michael Hallock
    Michael Hallock June 16th, 2010

    What about HtmlHelpers? The Html Helpers in MVC2 explicitly call to HttpUtility.HtmlEncode() and HttpUtiliy.HtmlAttributeEncode(). I'm assuming this doesn't fix that little hole?

  19. Avatar for Michael Hallock
    Michael Hallock June 16th, 2010

    Answered my own Question - The overridden class (HttpEncoder) is the class that HttpUtility.HtmlEncode, etc. use, so this WOULD in fact cover all of the HtmlHelper classes as well...
    Now I just have to upgrade to .NET 4.0...

  20. Avatar for Gustafson
    Gustafson January 28th, 2011

    Would it be possible for you, or someone else to set this up as a NuGet package...?
    It would be pretty sweet if all I needed to do to integrate this was to install a package...

  21. Avatar for Ashwani Kumar
    Ashwani Kumar January 28th, 2011

    Hello Phil,
    I tried using the code given for creating AntiXss encoder. It works fine for my most of the pages. But, on some of my pages I am using Google recaptcha, after using AntiXss encoder, the captcha is not working. Can u tell teh reason for that?
    Is there any way to know if a string is already encoded, so as to avoid double encoding?
    Thanks
    Ashwani

  22. Avatar for Gustafson
    Gustafson January 28th, 2011

    Is Encoder.HtmlEncode instead of AntiXss.HtmlEncode the new standard? the intellisense suggests that the latter is deprecated.
    Found the AntiXss dll in NuGet. Still need to write up the custom code though. fortunately it was a simple adjustment.

  23. Avatar for Baakka
    Baakka January 31st, 2013

    xzczxczxc

  24. Avatar for Tarek
    Tarek August 12th, 2013

    It seems that the developer does not need to care about XSS in MVC 4 since the url is already encoded by default!