How to: Display Safe Error Messages

When your application displays error messages, it should not give away information that a malicious user might find helpful in attacking your system. For example, if your application unsuccessfully tries to log in to a database, it should not display an error message that includes the user name it is using.

There are a number of ways to control error messages, including the following:

  • Configure the application not to show verbose error messages to remote users. (Remote users are those who are not requesting pages while working on the Web server computer.) You can optionally redirect errors to an application page.

  • Include error handling whenever practical and construct your own error messages. In your error handler, you can test to see whether the user is local and react accordingly.

  • Create a global error handler at the page or application level that catches all unhandled exceptions and routes them to a generic error page. That way, even if you did not anticipate a problem, at least users will not see an exception page.

To configure the application to turn off errors for remote users

  • In the Web.config file for your application, make the following changes to the customErrors element:

    • Set the mode attribute to RemoteOnly (case-sensitive). This configures the application to show detailed errors only to local users (that is, to you, the developer).

    • Optionally include a defaultRedirect attribute that points to an application error page.

    • Optionally include <error> elements that redirect specific errors to specific pages. For example, you can redirect standard 404 errors (page not found) to your own application page.

    The following code example shows a typicalcustomErrorsblock in the Web.config file.

    <customErrors mode="RemoteOnly" defaultRedirect="AppErrors.aspx"> 
       <error statusCode="404" redirect="NoSuchPage.aspx"/> 
       <error statusCode="403" redirect="NoAccessAllowed.aspx"/> 
    </customErrors> 
    

To include error handling

  1. Use a try-catch block around any statements that might generate errors.

  2. Optionally, test for a local user with the IsLocal property and modify error handling accordingly. The value 127.0.0.1 is equivalent to localhost and indicates that the browser is on the same computer as the Web server.

    The following code example shows an error-handling block. If an error occurs, a session state variable is loaded with details about the message, and the application then displays a page that can read the Session variable and display the error. (The error is deliberately written to provide no exploitable details to the user.) If the user is local, different error details are provided. In the finally block, an open resource is released.

    Try
       SqlConnection1.Open()
       SqlDataAdapter1.Fill(Me.DsPubs1)
    Catch ex As Exception
       If Request.IsLocal Then
          Session("CurrentError") = ex.Message
        Else
          Session("CurrentError") = "Error processing page."
        End If
        Server.Transfer("ApplicationError.aspx")
    Finally
           SqlConnection1.Close()
    End Try
    
    try
    {
        sqlConnection1.Open();
        sqlDataAdapter1.Fill(dsCustomers1);
    }
    catch (Exception ex)
    {
        if(Request.IsLocal)
        { Session["CurrentError"] = ex.Message; }
        else
        { Session["CurrentError"] = "Error processing page."; }
        Server.Transfer("ApplicationError.aspx");
    }
    finally 
    {
        this.sqlConnection1.Close();
    }
    

Creating a Global Error Handler

You can also create an error handler that catches all unhandled exceptions at the page level or for the application as a whole.

To create a global error handler

  • To create a global handler in a page, create a handler for the System.Web.UI.TemplateControl.Error event. To create an application-wide error handler, in the Global.asax file, add code to the System.Web.HttpApplication.Error event. These methods are called if an unhandled exception occurs anywhere in your page or application, respectively. You can get information about the most recent error from the GetLastError method.

    NoteNote

    If you have a global error handler, it takes precedence over error handling specified in the defaultRedirect attribute of the customErrors configuration element.

    The following code example shows a handler that gets information about the current error, puts it into a Session variable, and then calls a generic error-handling page that can extract and display the error information.

    Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
        Session("CurrentError") = "Global: " & _
            Server.GetLastError.Message
        Server.Transfer("lasterr.aspx")
    End Sub
    
    protected void Application_Error(Object sender, EventArgs e)
    {
        Session["CurrentError"] = "Global: " + 
            Server.GetLastError().Message;
        Server.Transfer("lasterr.aspx");
    }
    

See Also

Other Resources

ASP.NET Web Site Security