In the first two blog posts in this series we explored how we can implement Input and Output Validation using the OWASP ESAPI. We saw that every time a validation exception was encountered the ESAPI would throw something like an EncodingException, ValidationException or IntrusionException which returns a sanitised error message for us. We are going to cover Error Handling using the ESAPI in this blog post which will explain how the ESAPI exception handling works and how it can help you ensure that your own applications return sanitised error messages.
Every application will eventually have to deal with an exception and it is vital that these are handled securely. If an attacker can force exceptions to occur and you fail to correctly handle these situations you will expose sensitive information about the inner workings of the application. These detailed error messages will help attackers build a picture of your application and fine tune their attacks.
An attack such as SQL Injection will become significantly easier to exploit if an attacker can view the internal server error messages. I have included an example of an attempted attack and the unsanitised error message that is returned to the attacker below:
http://www.examplesite.com/home.html?day=Monday AND userscolumn= 2
You can see that the attacker appended AND userscolumn=2 onto the URL to test for a SQL Injection vulnerability. The attacker input was processed by the SQL Server which caused an exception to occur because the userscolumn doesn’t exist:
Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)
[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid column name ‘userscolumn’.
/examplesite/login.asp, line 10
This type of error message is a common sight across the internet and it will help attackers fine tune their attacks against your application.
To prevent these kinds of errors reaching the end users of your application you need to ensure that you develop your code to handle expected and unexpected exceptions. The errors that are returned to the end users should be generic messages such as “Server error – please contact support”.
How does error handling work in the ESAPI?
All of the exception handlers in the ESAPI extend the EnterpriseSecurityException class which itself extends the Java Exception class. The thing I probably like the most about the exception handlers in ESAPI is the ability to create two log messages easily from every exception we catch. This allows us to show a sanitised error message to the application user and also log a more descriptive error message internally to help us troubleshoot the issue. We can see below that EncodingException will have a userMessage and a logMessage:
We have two parameters which allows us to create the two error messages I mentioned above. The userMessage will be the sanitised error message that we will return to the application users whilst the logMessage parameter will contain our more detailed internal error message. The logMessage parameter will automatically log the error message to your log file.
In our Output Validation post we explored the encodeForURL method and saw that if an error occurs we will throw an EncodingException:
We can see that the reference implementation of the ESAPI checks if a valid encoding method is being used and throws an exception if an unsupported encoding type is being used or the decoding fails.
In both cases the same sanitised error message is returned to the application user but different error messages are logged to our log file which gives us more information about the two specific exceptions.
Lets take a look at another exception handler. In our first post in this series we looked at Input Validation with the ESAPI and we saw that by using a method called isValidCreditCard we could check whether user supplied input matched our credit card data type. If the input didn’t match our data type we would throw an IntrustionException as you can see below:
The IntrusionException is very similar to the EncodingException as it will also create two separate error messages but you can see that in the example below we are also specifying a log type (SECURITY) as well:
A secure approach to Error Handling
There are several simple points to remember when you are trying to implement secure error handling. Never include any of the following in the errors you return to the users of your application:
- The file that the exception occurred in
- The line that the exception occurred on
- The method that encountered an exception
- Any stack traces from the exception
- File system paths
- Service information such as ASP.NET version numbers
Authentication and Authorisation
I hope you have found this blog post useful, please do contact me with any feedback you have!