ASP.NET Request.Querystring with escaped ampersands

Posted by William on Apr 29, 2009

Take the following url “/images/myimage.jpg&width=300″. URL Encoding has no support whatsoever for HTML Encoding so passing an escaped ampersand html entity though a url in this format is illegal. Now, you may well be thinking “Hold on a minute William, I need to escape my ampersands to have valid XHTML markup on my pages”. Your right, and doing so is fine. Your browser does not pass the escaped ampersand in it’s request. It strips html encoding out before the request is made.

Moronic robots and such are not as thoughtful. They simply see the url and request it. When the request is handled your code will probably be calling Request.QueryString, but it will not get the value expected, potentially causing havoc with your web application.

Let’s step through the process involved in duplicating this problem (no querystring validation is used in this demonstration)

Imagine you have an ASP.NET image handler which takes querystring parameters to resize images. A general url to this handler will look like

1
/imagehandler.axd?path=/images/myimage.jpg&width=300

When rendered to the browser in an image tag the url will be encoded to be valid markup.

1
<img src="/imagehandler.axd?path=/images/myimage.jpg&amp;width=300" alt="image alt" />

A robot comes in, sees this url and requests it as is.

1
/imagehandler.axd?path=/images/myimage.jpg&amp;width=300

Your image handler calls Request.QueryString["width"], which you would expect in this case to return 300. However, nothing is returned. This is because the name/value pair is actually now amp;width=300 instead of width=300 because in properly formatted url’s name/value pairs are separated by the & character.

I recently had this issue and simply decoded any HTML entities in the url before working with the Request object. Here is my solution.

1
2
// Handle invalid requests where HTML encoding is passed in the querystring.
context.RewritePath(context.Server.HtmlDecode(context.Request.Url.PathAndQuery));

Admittedly it is rare to come across this behaviour because in most cases you are protected by the browser decoding html entities before the new requests are made. If you are tracking errors on your applications there is more chance of you noticing it, but being aware of it will help you out greatly when debugging those random request errors.