Proper Error Reporting and the Stack Trace

Quite often, sites go into production with the <customErrors mode=”off”> attribute set in the web.config. This isn't specific to ASP.NET MVC, but it's worth bringing up in the security chapter because it happens all too often.

There are three possible settings for the customErrors mode.

  • On is the safest for production servers, because it always hides error messages.
  • RemoteOnly shows generic errors to most users, but exposes the full error messages to users with server access.
  • The most vulnerable setting is Off, which exposes detailed error messages to anyone who visits your website.

Detailed error messages can expose information about how your application works. Hackers can exploit this by forcing your site to fail — perhaps sending in bad information to a controller using a malformed URL or tweaking the query string to send in a string when an integer is required.

It's tempting to temporarily turn off the Custom Errors feature when troubleshooting a problem on your production server, but if you leave Custom Errors disabled (mode=”Off”) and an exception occurs, the ASP.NET run time shows a detailed error message, which also shows the source code where the error happened. If someone was so inclined, they could steal a lot of your source and find (potential) vulnerabilities that they could exploit in order to steal data or shut your application down.

The root cause of this problem is waiting for an emergency to think about error handling, so the obvious solution is to think about error handing before the emergency hits.

Using Configuration Transforms

If you'll need access to detailed errors on other servers (e.g., in a stage or test environment), I recommend you use web.config transforms to manage the customErrors setting based on the build configuration. When you create a new ASP.NET MVC 4 application, it will already have configuration transforms set up for debug and release configurations, and you can easily add additional transforms for other environments. The Web.Release.config transform file, which is included in an ASP.NET MVC application, contains the following code:

  <system.web>
   <compilation xdt:Transform="RemoveAttributes(debug)" />
   <!--
     In the example below, the "Replace" transform will replace the entire
     <customErrors> section of your web.config file.
     Note that because there is only one customErrors section under the
     <system.web> node, there is no need to use the "xdt:Locator" attribute.
     <customErrors defaultRedirect="GenericError.htm"
       mode="RemoteOnly" xdt:Transform="Replace">
       <error statusCode="500" redirect="InternalError.htm"/>
     </customErrors>
   -->
 </system.web>

This transform includes a commented out section that replaces the customErrors mode with RemoteOnly when you build your application in Release mode. Turning this configuration transform on is as simple as uncommenting the customErrors node, as shown in the following code:

<system.web>
   <compilation xdt:Transform="RemoveAttributes(debug)" />
   <!--
     In the example below, the "Replace" transform will replace the entire
     <customErrors> section of your web.config file.
     Note that because there is only one customErrors section under the
     <system.web> node, there is no need to use the "xdt:Locator" attribute.
-->
     <customErrors defaultRedirect="GenericError.htm"
       mode="RemoteOnly" xdt:Transform="Replace">
       <error statusCode="500" redirect="InternalError.htm"/>
     </customErrors>
 </system.web>

Using Retail Deployment Configuration in Production

Rather than fiddle with individual configuration settings, you can make use of a useful (yet sadly underutilized) feature in ASP.NET: the retail deployment configuration.

This is a simple switch in your server's machine.config file (found at %windir%Microsoft.NETFramework<frameworkversion>Config) that tells ASP.NET whether it is running in retail deployment mode. The deployment configuration just has two settings: Retail can be either true or false. The deployment / retail value defaults to false; you can set it to true with the following configuration setting:

<system.web>
  <deployment retail="true" />
</system.web>

Setting deployment / retail to true does a few things:

  • customErrors mode is set to On (the most secure setting).
  • Trace output is disabled.
  • Debug is disabled.

These settings override any application-level settings in web.config.

Using a Dedicated Error Logging System

The best solution is to never turn off custom errors in any environment. Instead, I recommend that you make use of a dedicated error logging system like ELMAH (mentioned previously in this chapter). ELMAH is a free library available via NuGet, and offers a variety of methods for viewing your error information securely. For instance, you can have ELMAH write error information to a database table, which is never exposed on your website.

You can read more about how to configure and use ELMAH at http://code.google.com/p/elmah/.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset