3

In our asp.net web page (.net 4.7.2) we use custom exception rendering logic which creates specific error pages for the user in global.asax.cs via:

Application_Error(object sender, EventArgs e)

This works fine. However there are some asp.net errors which never hit the Application_Error-event.
For those errors, we set explicitly an error page in the web.config via the customErrors-element. This looks like this:

<customErrors mode="On" defaultRedirect="~/CustomErrors/FatalError.aspx" redirectMode="ResponseRewrite"  />

The Problem
The above works fine in most of the cases. However, there are some few asp.net errors, which are not handled by the Application_Error event and also bring the FatalError.aspx to throw an exception, even if there is no asp-code within. A good example of such an error is, when you type the following reserved address into your browser:

https://[yourWebsite]/com1

This blows the .aspx- based default error page with the following error message (Http-Status-Code 500):

An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.

Even setting an aspx-file which has absolutely no asp-code within, leads to this error. The same happens also, if the defaultRedirect-attribute is configured to a resource which not exists! It also doesn't make any difference, if there are explict error-elements defined under the customErrors-element, which define the redirect-resource based on an explicit http statusCode.

When setting the redirectMode of the customErrors-element to ResponseRedirect, the aspx-based default error handler works fine. However, this is not option, since our client don’t want to see the redirect.

As a workaround, we can try to use a static html file. However, in this case, asp.net sends the response without the correct content-type back to the browser and the HTML-page is rendered as text.
There are lot of posts throughout the internet which state this an error. However, the proposed solution is always either, to use an .aspx-file, or to use the Application_Error event in global.asax.cs to set the content-type manually in code. However, both variants are not possible in this very situation as described above (every aspx-file blows and Application_Error is never called).

Question
How can we configure a reliable error handling, which never shows any asp.net specific error-information but an application specific one, even with such edge cases as described in this post.
Please note, the question is not about how to circumvent the error with the reserved resource names. This is only an example and there are probably many more other circumstances, where asp.net errors occur, which never reach the Application_Error event and bring aspx-based error files down. The goal is really to have a mechanism for rendering application branded error message instead of asp.net error messages, which works fully reliable.

Also as a side node, we use also the httpErrors-element in the webServer-section to change errors which stem not from asp.net but from IIS itself. However, we have not observed any dependency to the problem described above, hence, I have not mentioned that in the main text.

HCL
  • 36,053
  • 27
  • 163
  • 213
  • you could use iis URL rewrite custom response it will work with every browser.also try to set "show friendly HTTP error message" in internet explorer setting [image](https://i.imgur.com/TqTDOQL.png) – Jalpa Panchal Mar 22 '21 at 13:36
  • @Jalpa Pnachal: Hi, may you elaborate, how the rewrite could help? – HCL Mar 22 '21 at 15:50

2 Answers2

1

The errors are not pass from Application_Error pass from IIS. You can configure this errors on web.config on this session.

Here is an example to hand the not found page, witch means most of the errors that not go through Application_Error.

403 error is for Forbidder errors.

<system.webServer>
    <httpErrors>
      <remove statusCode="404" subStatusCode="-1" />
      <remove statusCode="403" subStatusCode="-1" />      
      <error statusCode="404" prefixLanguageFilePath="" path="/PageNotFound.aspx" responseMode="ExecuteURL" />
      <error statusCode="403" prefixLanguageFilePath="" path="/PageNotFound.aspx" responseMode="ExecuteURL" />        
     </httpErrors>
</system.webServer>

How I use the Application_Error on global.asax

void Application_Error(object sender, EventArgs e)
{
    // log the last error
    Exception LastOneError = Server.GetLastError();

    string cTheFile = HttpContext.Current.Request.Path;

    if (!cTheFile.EndsWith("PageNotFound.aspx", StringComparison.InvariantCultureIgnoreCase))
    {
        // check for this above -> fPageNotExist
        // reference: https://stackoverflow.com/a/14032497/159270
        if(fPageNotExist)
            Response.Redirect("~/PageNotFound.aspx");
        else
            Server.Transfer("~/PageNotFound.aspx");
    }
}

and as you write also use

<customErrors mode="On" defaultRedirect="~/error.aspx" redirectMode="ResponseRewrite">

The COM1-9, LPT1-9, AUX, PRT, NUL, CON files that are pseudofiles can be avoided using this option on web.config - its for IIS

<configuration>
  <system.web>
    <httpRuntime relaxedUrlToFileSystemMapping="true"   ....other settings.... />

   </system.web>
</configuration>

by setting this option you get this files again under asp.net - but I will not recommented to do so, because this requests are not come from regular use of your system, and may not be not be protected well if you put it on true.

web forms and viewStateKey

For web forms, one more point that I check for errors is on viewStateKey post value - for more details you can read this q/a:

CryptographicException: Padding is invalid and cannot be removed and Validation of viewstate MAC failed

Aristos
  • 66,005
  • 16
  • 114
  • 150
  • Hi, thanks. This is almost exactly, how we built our configuration (see also the last section of my post). This works in 99.9%, but there are some strange edge cases, as described in my post, which are not handled by IIS but asp.net but blow the whole exception handling. Please check it in one of your (probably MVC-) solutions. Call "http[s]://[yourWebsite]/com1". This will blow your "error.aspx" and will not call "Application_Error". The error stems not from IIS (you will see, if you get it), hence the "httpErrors"-section will not help. Its this edge cases I'm interested in to resolve. – HCL Mar 22 '21 at 06:41
  • As a side note, one can use relaxedUrlToFileSystemMapping="true" in sytem.web. However I'm interested in making the error handling more robust and not to supress this very error, since there are probably more such cases out there and its impossible to find and suppress them all. Besides, its not really clear what does relaxedUrlToFileSystemMapping from a security standpoint of view. – HCL Mar 22 '21 at 06:58
  • @HCL I have update my answer with the solution for this specific pseudofiles - any other specific example ? – Aristos Mar 23 '21 at 12:11
  • Hi your change is exactly what I described in my second comment. I would not enable this for security reasons. Additionally, as I stated in my post, I'm not interested in disabling this very error but to get an exception visualization which is absolutely waterproof. And for doing so, this reserved addresses are perfectly to test. Currently, I'm a bit further and will post soon another question, which may dig more in the right direction. But thanks for your post anyway. I think its already really sophisticated, since error handling in asp.net seems to me pretty difficult to get right. – HCL Mar 23 '21 at 12:46
  • please see https://stackoverflow.com/questions/66763502/how-to-prevent-mvc5-setting-the-ftryskipcustomerrors-flag-to-true-automatically – HCL Mar 23 '21 at 12:52
  • @HCL error handling for regular users is not that sophisticated as you say - if they follow your path - the difficult is to handle the attackers - – Aristos Mar 23 '21 at 20:21
  • 1
    We went to great lengths to hide information about the server from the hacker (removing any treacherous headers etcetera). For the very same reason, we require that never ever a specific asp.net or IIS error is shown to the user (attacker). In principle, this is easy. Use existingResponse="Replace". However, on the other hand, we have the goal to show user friendly messages, including also a support code, which helps identify errors in the logs. And there begins the hazzle. You can have fulfilled one goal or the other. However, to get both, seems quite a struggle. – HCL Mar 24 '21 at 06:54
-2
<system.web>
<customErrors mode=”On” redirectMode=”ResponseRewrite”>
<error statusCode=”500″ redirect=”~/errorpages/500.aspx” />
</customErrors>
</system.web>
Juan Ozuna
  • 32
  • 4
  • Welcome, Juan. @HCL included the `` option in their original post—but then explained why it doesn't fully satisfy their needs. This answer doesn't address the core concerns animating this question. – Jeremy Caney Mar 27 '21 at 20:14