Skip to main content

Insecure exceptions - Empty or no catch

Need

Proper exception handling and error management

Context

  • Usage of C# for developing robust and efficient applications

Description

Non compliant code

public IActionResult Index()
{
try
{
// Some code that can throw an exception
int a = 0;
int b = 1 / a;
}
catch
{
// Empty catch block
}

return View();
}

In the above code, we have a try block where we are performing some operations that can potentially throw an exception. Here, we are trying to divide a number by zero which will throw a DivideByZeroException.

However, the catch block that follows the try block is empty. This means that if an exception is thrown in the try block, the catch block will catch it but it won't do anything about it. This is a bad practice because it silently swallows the exception and makes it hard to debug issues. It can also lead to unexpected behavior in the application.

Moreover, the application can become temporarily or permanently unavailable if the exception is critical. This is because the application is not properly handling the exception and is just ignoring it.

This is an example of the "Insecure Exceptions - Empty or No Catch" vulnerability. Proper exception handling is crucial in any application to ensure that it can recover from errors and continue to function correctly.

Steps

  • Identify the specific exception that can be thrown in the try block.
  • Replace the empty catch block with a catch block that handles the specific exception.
  • Handle the exception appropriately, such as logging the error, displaying a user-friendly error message, or taking corrective actions.
  • Consider using multiple catch blocks to handle different types of exceptions if necessary.
  • Ensure that the catch block does not swallow the exception and prevents the application from crashing.
  • Implement a global exception handling mechanism to handle unhandled exceptions and provide a consistent error handling approach throughout the application.

Compliant code

public IActionResult Index()
{
try
{
// Some code that can throw an exception
int a = 0;
int b = 1 / a;
}
catch (DivideByZeroException ex)
{
// Log the error
Console.WriteLine($"An error occurred: {ex.Message}");
// Display a user-friendly error message
ModelState.AddModelError("", "An error occurred while processing your request. Please try again later.");
// Consider taking corrective actions
}
catch (Exception ex)
{
// Log the error
Console.WriteLine($"An unexpected error occurred: {ex.Message}");
// Display a user-friendly error message
ModelState.AddModelError("", "An unexpected error occurred. Please try again later.");
}

return View();
}

The updated code now handles exceptions properly. The try block contains the code that might throw an exception. In this case, a DivideByZeroException can be thrown when trying to divide by zero.

The catch (DivideByZeroException ex) block catches this specific type of exception. Inside this block, the error is logged to the console, a user-friendly error message is added to the model state, and corrective actions can be considered.

The catch (Exception ex) block catches all other types of exceptions. This is a good practice to ensure that any unexpected exceptions are also handled and do not crash the application. Inside this block, the error is also logged to the console and a user-friendly error message is added to the model state.

This approach ensures that exceptions do not go unhandled, providing a better user experience and making the application more robust. It's also recommended to implement a global exception handling mechanism to handle unhandled exceptions and provide a consistent error handling approach throughout the application.

References