One of the things I try to hammer home in my presentation is you should never emit user input without making it safe. The HttpUtility class provides developers with two main methods for this, HtmlEncode and UrlEncode.

HtmlEncode will take a string and escape it so that it is safely displayable on screen, removing the risk of Cross Site Scripting attacks. UrlEncode takes a string and escapes it to a format suitable for use in a URL and is usually used to encode query values, escaping such characters as = and & into their encoded values; but what happens if you have a complete URI and push it through UrlEncode?

Well, it gets mangled. If I take the following URI from my referral logs

http://google.com/search?hl=en&lr=&safe=off&q="key+
renewal+period"+wpa

and push it through UrlEncode I get

http%3a%2f%2fgoogle.com%2fsearch%3fhl%3den%26lr%3d
%26safe%3doff%26q%3d%22key%2brenewal%2bperiod
%22%2bwpa

The UrlEncode method has escaped everything, not, as I probably wanted, just the query values. That's really not much good to me. Obviously I don't want to echo a potentially unsafe URL into an <a href> tag as judicious use of a single quote, such as that in the example above would open me up to XSS.

With version 2 of the .NET framework Microsoft delivered a function to escape a complete URL correctly, a method on the URI class. The URI class has been long used to get at various parts of a URI without having to do any of the heaving lifting yourself. Unfortunately in earlier versions of the framework you'd still have to do a lot of work yourself as the ToString() representation of a URI can still be unsafe. For example creating a new URI object and loading the example URI above then calling ToString() gives me

http://google.com/search?hl=en&lr=&safe=off&q="key+
renewal+period"+wpa

which, whilst correct, isn't safe, in fact it's just the original string I loaded in. Help is at hand however, in the shape of the EscapeUriString method. A call to that gives us

http://google.com/search?hl=en&lr=&safe=off&
q=%22key+renewal+period%22+wpa

Safety at last. EscapeUriString is also static, so you don't need to construct a URI object to use it, simply call Uri.EscapeUriString(badUrl);

What can you do if you're using .NET 1.0 or 1.1? Use the EscapeString method. Both these methods do pretty much the same thing, calling a private unsafe method to do the work for you.