15

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 /%.

3
  • 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, 2011 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, 2011 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, 2012 at 19:26

4 Answers 4

21
+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.

11
  • 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, 2011 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. Apr 14, 2011 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, 2011 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, 2011 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). Apr 14, 2011 at 17:53
4

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?

3

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

4
  • 5
    None of these work - IIS never passes along the request.
    – bkaid
    Apr 12, 2011 at 16:12
  • Option #1 should work no matter what because that is how IIS responds to the error
    – Dave Wise
    Apr 12, 2011 at 16:53
  • 5
    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, 2011 at 19:15
  • This option work for all errors outside the ones blocked from the iis kernel (see the answer from Scott Forsyth - MVP). If your application returns for example HttpStatusCodeResult(HttpStatusCode.BadRequest) somewhere, it will be redirected to the custom error page as expected in option 1. or 2. Nov 19, 2020 at 16:14
2

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.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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