I am looking for any kind of solution to properly get an IIS request such as https://stackoverflow.com/% and http://bing.com/% to not display a 400 Bad Request page, but display a custom error page similar to how http://google.com/% and http://facebook.com/% do (obviously those examples are not on IIS).
I believe I have tried setting all the applicable http.sys registry settings (AllowRestrictedChars, PercentUAllowed) per http://support.microsoft.com/kb/820129 but that has not helped. Setting AllowRestrictedChars and a custom 400 page has fixed urls such as https://stackoverflow.com/%12 but not /%.
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:
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:
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
Change IIS to point to a custom page for 400 errors than it does normally
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>
Write an httpModule that inspects the incoming URLs and handles them
This post on the IIS forum indicates that HTTP 400 (Bad Request) are blocked by http.sys and don't make it to IIS which matches the links that @Scott Forsyth - MVP included on his original answer.
You can see a log of these requests under c:\Windows\System32\LogFiles\HTTPERR\
I don't know if you can configure the response page that is sent back to the user for these kind of error but since even Bing suffers from this issue I suspect that's either not possible or would require some horrible system hacks.