Properly handle IIS request with percent sign in url (/%)

This is blocked right in the IIS kernel level. As a test I pulled out every module in IIS so that it didn't even have a static page handler, and it still displayed the 400 error message.

I don't believe it's possible with IIS to get around that. The registry settings you mentioned are for other types of restricted characters. I haven't seen a lever to change that functionality.

What's your goal is avoiding that? It opens your attack surface wider, and I can't imagine a legit visitor being lost as a result of blocking incomplete URL escape sequences.

Update2: Here are three great links on this. Both Nazim Lala and Wade Hilmo from the IIS team have blogged about this because of discussion around your question. Also Scott Hanselman has a great post on the querystring part within .NET:

  • Use of Special Characters in IIS - Nazim Lala
  • How IIS block characters in URLs - Wade Hilmo
  • Experiments in Wackiness - Scott Hanselman

Update: I checked with a member of the IIS team to get an authoritative answer. He mentioned that the % is considered an unsafe character according to RFC 1738 (http://www.ietf.org/rfc/rfc1738.txt).

Here's the relevent text:

Unsafe:

Characters can be unsafe for a number of reasons. The space character is unsafe because significant spaces may disappear and insignificant spaces may be introduced when URLs are transcribed or typeset or subjected to the treatment of word-processing programs. The characters "<" and ">" are unsafe because they are used as the delimiters around URLs in free text; the quote mark (""") is used to delimit URLs in some systems. The character "#" is unsafe and should always be encoded because it is used in World Wide Web and in other systems to delimit a URL from a fragment/anchor identifier that might follow it. The character "%" is unsafe because it is used for encodings of other characters. Other characters are unsafe because gateways and other transport agents are known to sometimes modify such characters. These characters are "{", "}", "|", "\", "^", "~", "[", "]", and "`".

All unsafe characters must always be encoded within a URL. For example, the character "#" must be encoded within URLs even in systems that do not normally deal with fragment or anchor identifiers, so that if the URL is copied into another system that does use them, it will not be necessary to change the URL encoding.

So IIS proactively blocks this up at the core level, a proactive security measure to minimize their attack surface.


The only way around this sounds like checking the URL before the IIS kernel can.

You'd need to send your dynamically generated links through a script to check them before forwarding your end-user on to that URL...

Barring that, you know this is the only situation where IIS won't handle it the way you want. So, by process of elimination, if you have an unhandled request you know what caused it.

Perhaps checking referrer in a custom 400 page would assist in narrowing down the source of the traffic?


I can think of 3 possible ways

  1. Change IIS to point to a custom page for 400 errors than it does normally

  2. If this is unique to a specific web site in IIS, you can do something like this in the web.config:

    <customErrors defaultRedirect="ErrorPage.aspx" mode="On">
    <error statusCode="400" redirect="myCustom400Error.aspx" />
    </customErrors>

  3. Write an httpModule that inspects the incoming URLs and handles them