This is the second part of the multi-part series on writing secure ASP.NET code. The post series was inspired by the online training class Creating Secure Code for ASP.NET offered by TeamProfessor from Security Innovations. In the first part I covered input data validation and types of online attacks such as SQL injection and HTTP Response splitting. Today, I am going to discuss best practices for secure error handling.
Error handling plays an important role during application design. For application to be secure, it must be able to handle errors and never enter an unknown state. Entering the unknown state may compromise the integrity and availability of the data. If an exceptional condition occurs, the application should fail to a secure state. The critical tasks should execute as atomic transactions. It means that the task should either complete successfully or have no effect on the system. The error messages displayed to the user should be generic and provide no information about the culprit of the issue.. For instance, during log-on process, if incorrect password was entered, the error message displayed to the user should be generic so that it does not reveal the details of the failed log-on attempt. The message could state that log-on failed. The error message should not mention that incorrect password was entered. If it did, then it would let the attacker know that the user exists on the system and he would only need to guess the password in order to compromise the system.
Exception handling needs to be implemented with specific structured handlers. The most specific exception (InvalidArgumentException, DivideByZeroException , etc) should be the first one in the catch block and the most generic one, unhandled exception (Exception) should be the last one. The unhandled exceptions should be handled by a global exception handler in order to the minimize risk of information disclosure and improve application’s robustness. The exception handling should only be used for catching truly exceptional conditions that cannot be handled otherwise. It should not be used to hide casting or any other type of errors. Having an empty catch block is extremely dangerous because it hides the exception and allows an application to enter an insecure state and continue execution. It also makes debugging tougher. The catch block should handle the exception and release the resources by disposing objects, closing database connections, files, etc. It is a common practice to log exceptions to a file, event log, or some other location. The information logged should not contain any sensitive information.
In the next week’s post I will discuss best practices for storing sensitive data and web application configuration.