Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am looking for any kind of solution to properly get an IIS request such as http://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 http://stackoverflow.com/%12 but not /%.

share|improve this question
3  
You realise that it's an incomplete URL-escape and is a bad request, so 400 is properly handling it? PercentU and AllowRestricted aren't really applicable –  Rup Apr 11 '11 at 17:51
    
Yes I do (and /% is just an example URL, but obviously the error happens with every invalid escape character). IIS is handling the 400, but I want to show a custom 400 page like I can with other status codes in IIS, and like how non-IIS servers can for 400. –  bkaid Apr 11 '11 at 21:06
    
I have some powerful links pointing to my websites that are mistakenly encoded like this. but I'm not allowed to 301 them to the correct page, instead it's a hard error. this is unacceptable. –  boomhauer Sep 27 '12 at 19:26
add comment

4 Answers

up vote 13 down vote accepted
+50

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:

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.

share|improve this answer
    
I prefer to properly log and handle all errors myself to monitor any invalid strange combination of invalid urls that are getting dynamically generated on my site - in the event one isn't getting properly url escaped. –  bkaid Apr 12 '11 at 23:45
1  
There's something to be said for handling the errors yourself, but if the blatantly obvious failures are handled for you, that's a nice bonus. IIS shouldn't allow characters through that don't correspond to a file or folder in the NTFS file system. It wouldn't know what to do with the folder path. If it isn't a character pattern that equals a valid character, then it would need to make a decision on what to do. In this case it appears that it was dedicated to block rather than ignore the invalid characters. –  Scott Forsyth - MVP Apr 14 '11 at 13:11
    
@thekaido As Scott said it doesn't make sense to parse incomplete URLS. What sort of custom error page can you make since you have no idea what the user was trying to do (since the request is incomplete). Note that IE9 won't even let you get to the server with an incomplete request –  Jim B Apr 14 '11 at 14:35
    
I understand the implications of all of these things but Apache and other web servers allow for it as should IIS. Improperly escaped URL's are the only URL's IIS won't let you handle that I know of. IIS should and does allow other characters that don't maps to the NTFS file system because my site is built using ASP.NET MVC where requests will be routed to non-file based resources. –  bkaid Apr 14 '11 at 16:03
    
Actually I stand corrected about the % in NTFS. It's allowed, along with most other characters: en.wikipedia.org/wiki/Ntfs. (search for Allowed characters in filenames). –  Scott Forsyth - MVP Apr 14 '11 at 17:53
show 5 more comments

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.

share|improve this answer
add comment

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?

share|improve this answer
add comment

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

share|improve this answer
2  
None of these work - IIS never passes along the request. –  bkaid Apr 12 '11 at 16:12
    
Option #1 should work no matter what because that is how IIS responds to the error –  Dave Wise Apr 12 '11 at 16:53
2  
I just tried option 1 and #2 again and neither of them work. IIS is handling this request specially like Scott mentions. –  bkaid Apr 12 '11 at 19:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.