I've written an application that handles most exceptions gracefully, with the page's design intact and a pretty error message. My application catches them all in the Page_Error
event and there adds the exception to HttpContext.Curent.Context.Items
and then does a Server.Transfer
to an Error.aspx
page. I find this to be the only viable solution in ASP.NET as there seems to be no other way to do it in a centralized and generic manner.
I also handle the Application_Error
and there I do some inspection on the exception that occurred to find out if I can handle it gracefully or not. Exceptions I've found I can handle gracefully are such that are thrown after someone hacking the URI to contain characters the .NET framework considers dangerous or basically just illegal at the file system level.
Such URIs can look like e.g.:
http://exmample.com/"illegal"
http://example.com/illegal"/
http://example.com/illegal /
(notice the space before the slash at the end of the last URI).
I'd like these URIs to respond with a "404 Not Found" and a friendly message as well as not causing any error report to be sent to avoid DDOS attack vectors and such. I have, however, not found an elegant way to catch these types of errors. What I do now is inspect the exception.TargetSite.Name
property, and if it's equal to CheckInvalidPathChars
, ValidatePath
or CheckSuspiciousPhysicalPath
, I consider it a "path validation exception" and respond with a 404.
This seems like a hack, though. First, the list of method names is probably not complete in any way and second, there's the possibility that these method names gets replaced or renamed down the line which will cause my code to break.
Does anyone have an idea how I can handle this less hard-coded and much more future-proof way?
PS: I'm using System.Web.Routing
in my application to have clean and sensible URIs, if that is of any importance to any given solution.
I don't think using System.Web.IHttpModule is the correct answer for IIS7+. I am trying to implement IHttpModule to validate the path but the exception has been thrown before the HttpModule is executed.
This is my exception stack:
and this is the link to Application Life Cycle for IIS 7.0 (http://msdn.microsoft.com/en-us/library/bb470252.aspx)
I am guessing that the exception caused by the "RESOLVE CACHE" step
It may be that System.Web.Routing supports some sort of url filtering, but it is quite easy to implement your own.
Look at the System.Web.IHttpModule interface and read about implementing custom HTTP Modules. Http modules enter that Asp.Net pipeline and run before your page is run. You can use it to perform logging of requests, to modify requests and in your case to filter requests. The Asp.Net routing module is also implemented as a custom HTTP Module.
What you can do is to implement a Http Module that looks at the requested url and check if it is valid. If the url is invalid you can do whatever you need, for example redirect it to your 404 - not found page or you can just stop the request.
Writing Custom HttpModule didn't work for me - I still got the "Illegal characters in path" error, but answer to this question solved the problem:
Turns out you could avoid this by setting allowDoubleEscaping="false" in for requestFiltering in web.Config. I.e:
Perhaps not the perfect solution (any suggestions for a better one is much appreciated), but it solves the problem.