I was starting to pull my hair out at work today. I have a website that is running in IIS 7.5 and uses custom 500 error pages. It is running with Integrated Pipeline and the web.config looks like this:
<customErrors mode=”On” defaultRedirect=”Error500.aspx” redirectMode=”ResponseRewrite” xdt:Transform=”Replace”>
<error statusCode=”404″ redirect=”Error404.aspx”/>
<error statusCode=”500″ redirect=”Error500.aspx”/>
<remove statusCode=”500″ subStatusCode=”-1″ />
<remove statusCode=”403″ subStatusCode=”-1″ />
<remove statusCode=”404″ subStatusCode=”-1″ />
<error statusCode=”404″ prefixLanguageFilePath=”” path=”/Error404.aspx” responseMode=”ExecuteURL” />
<error statusCode=”403″ prefixLanguageFilePath=”” path=”/Error404.aspx” responseMode=”ExecuteURL” />
<error statusCode=”500″ prefixLanguageFilePath=”” path=”/Error500.aspx” responseMode=”ExecuteURL” />
Everything was working fine. An error would happen, the status code of 500 would get set and the user would get redirected to my custom error page. Then something weird came up. Through a security audit, it was brought up that adding <!–> into the query string would throw an application error with a 500 status and show server information. My custom error page was not getting fired. This was a bit strange.
Turns out, 2 things needed done to catch this.
First, I had a base class that ALL my pages derived from. In this base class I had to override the OnError method so that I could catch the error that was happening. I was using Server.Transfer to send users to my error pages already when my code needed to throw an error so I then called the method that was doing this error handling and thus calling Server.Transfer.
Unfortunately, that in itself wasn’t enough.
When I started investigating further, I noticed an overload for Server.Transfer that I didn’t notice before. It is called preserveForm. Since .Net was complaining about the query string having dangerous values, doing a Server.Transfer would transfer the request to another page and still have those dangerous value. By default, preserveForm is set to true and with it being true the get/post values are maintained. Setting this to false cleared out the bad querystring and allowed my custom error page to function properly.
Hopefully that helps someone else out there.