How to Use AntiXSS as default encoder in ASP.NET MVC 2?

Dec 11, 2010 at 7:43 AM
Edited Dec 11, 2010 at 7:45 AM

I'm now reading this book: Professional ASP.NET MVC 2 and when came to XSS the author recommended to use AntiXSS as default encoder.

A detailed article about this is available at

and the demo project is also available

When I open the downloaded demo project and attempted to run, I encountered an compilation error:

	"Could not load file or assembly 'AntiXssWeb' or one of its dependencies. The system cannot find the file specified."
Relational web.config:
		<httpRuntime encoderType="AntiXssEncoder, AntiXssWeb"/>
		<!--	...	-->
I don't really know how to use AntiXSS......

(The author used AntiXSS v3.1, but I am now using v4.0.)
Dec 12, 2010 at 4:50 PM

The namespaces changed between 3.1 and 4.0 to become Microsoft.Security.Application with the main class renamed to Encoder. So any references to AntiXss. should become Encoder.

However the error you're seeing does point to the DLL for Phil's class not being found. If you've dropped his code into your own web site then you'll need to update the config to be

<httpRuntime encoderType="AntiXssEncoder, yourAssemblyName"/>

where yourAssemblyName is the name of the assembly (without .dll) that the class resides in.

Eventually, when I get some time and budget I'm aiming to add the final encoding mechanism necessary to support everything that the ASP.NET encoder needs and then roll up my own class for this.

Dec 13, 2010 at 4:01 PM

Thanks, I use the AntiXssEncoder class written by Phil

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)

    protected override void HtmlAttributeEncode(string value, TextWriter output)

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

    protected override byte[] UrlEncode(byte[] bytes, int offset, int count)
        //Can't call AntiXss library because the AntiXss library works with Unicode strings.
        //This override works at a lower level with just a stream of bytes, independent of 
        //the original encoding.

        //Internal ASP.NET implementation reproduced below.
        int cSpaces = 0;
        int cUnsafe = 0;

        // count them first
        for (int i = 0; i < count; i++)
            char ch = (char)bytes[offset + i];

            if (ch == ' ')
            else if (!IsUrlSafeChar(ch))

        // nothing to expand?
        if (cSpaces == 0 && cUnsafe == 0)
            return bytes;

        // expand not 'safe' characters into %XX, spaces to +s
        byte[] expandedBytes = new byte[count + cUnsafe * 2];
        int pos = 0;

        for (int i = 0; i < count; i++)
            byte b = bytes[offset + i];
            char ch = (char)b;

            if (IsUrlSafeChar(ch))
                expandedBytes[pos++] = b;
            else if (ch == ' ')
                expandedBytes[pos++] = (byte)'+';
                expandedBytes[pos++] = (byte)'%';
                expandedBytes[pos++] = (byte)IntToHex((b >> 4) & 0xf);
                expandedBytes[pos++] = (byte)IntToHex(b & 0x0f);

        return expandedBytes;


    protected override string UrlPathEncode(string value)
        //AntiXss.UrlEncode is too "pessimistic" for how ASP.NET uses UrlPathEncode

        //ASP.NET's UrlPathEncode splits the query-string off, and then Url encodes
        //the Url path portion, encoding any parts that are non-ASCII, or that
        //are <= 0x20 or >=0x7F.

        //Additionally, it is expected that:
        //                       UrPathEncode(string) == UrlPathEncode(UrlPathEncode(string))
        //which is not the case for UrlEncode.

        //The Url needs to be separated into individual path segments, each of which
        //can then be Url encoded.
        string[] parts = value.Split("?".ToCharArray());
        string originalPath = parts[0];

        string originalQueryString = null;
        if (parts.Length == 2)
            originalQueryString = "?" + parts[1];

        string[] pathSegments = originalPath.Split("/".ToCharArray());

        for (int i = 0; i < pathSegments.Length; i++)
            pathSegments[i] = AntiXss.UrlEncode(pathSegments[i]);  //this step is currently too aggressive

        return String.Join("/", pathSegments) + originalQueryString;

    private bool IsUrlSafeChar(char ch)
        if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
            return true;

        switch (ch)

            //These are the characters ASP.NET considers safe by default
            //case '-':
            //case '_':
            //case '.':
            //case '!':
            //case '*':
            //case '\'':
            //case '(':
            //case ')':
            //    return true;

            //Modified list based on what AntiXss library allows from the ASCII character set
            case '-':
            case '_':
            case '.':
                return true;

        return false;

    private char IntToHex(int n)
        if (n <= 9)
            return (char)(n + (int)'0');
            return (char)(n - 10 + (int)'a');

and placed it at the root of my app. And I configure Web.config like this:

<httpRuntime encoderType="AntiXssEncoder"/>

At last, I call AntiXSS likt this:

<%=Microsoft.Security.Application.Encoder.HtmlEncode("<Script>") %>

I success!

But I think since Microsoft.Security.Application.AntiXss is obsolete in AntiXSS v4.0, I need to change the AntiXss.HtmlEncode method to Microsoft.Security.Application.Encoder.HtmlEncode

in the AntiXssEncoder class written by Phil.

Dec 13, 2010 at 4:11 PM

Yes - the encoder class is Phil's, it was only a proof of concept and done to prove the point, but done before we had our great renaming in antixss *grin*