Technical information leak - Stacktrace - C-Sharp

Technical information leak - Stacktrace - C-Sharp

Need

Prevention of technical information leakage from system error traces

Context

  • Usage of C# 7.0 for modern language features and enhancements
  • Usage of Microsoft.AspNetCore.Mvc for building web applications with ASP.NET Core

Description

Non compliant code

        public class HomeController : Controller
{
    public IActionResult Index()
    {
        try
        {
            // some code here which might throw an exception
        }
        catch (Exception ex)
        {
            return Content("An error occurred: " + ex.ToString());
        }
    }
}
        
        

In the above C# code snippet, we have a method Index() in the HomeController class of an ASP.NET Core application. This method is trying to execute some code which might throw an exception. If an exception is thrown, the catch block will handle it by returning a Content result that includes the full details of the exception.

The problem here is that the ex.ToString() method will include the full stack trace of the exception, which reveals technical details about the application's internals. This information can be useful for an attacker to understand the structure and behavior of the application, and to devise more effective attacks.

This is a classic example of an information leakage vulnerability, also known as an "information disclosure" vulnerability. The application is unintentionally revealing information that should be kept private.

The vulnerability exists in the catch block of the Index() method. Instead of returning a detailed error message to the client, the application should log the detailed error message for debugging purposes, and return a generic error message to the client.

Steps

  • Remove the catch block that returns the exception stack trace to the user.
  • Implement proper error handling and logging in the application.
  • Use a centralized exception handling mechanism, such as middleware or filters, to handle exceptions.
  • Return a generic error message to the user without exposing sensitive technical information.
  • Ensure that error messages do not reveal any internal system details or stack traces.

Compliant code

        public class HomeController : Controller
{
    public IActionResult Index()
    {
        try
        {
            // some code here which might throw an exception
        }
        catch (Exception ex)
        {
            // Log the exception details for debugging purposes
            Log.Error(ex, "An error occurred while processing the request.");

            // Return a generic error message to the user
            return Content("An error occurred while processing your request. Please try again later.");
        }
    }
}
        
        

The original code was vulnerable to a technical information leak, specifically a stack trace. This is because it was returning the full details of any exceptions that occurred directly to the user. This information could potentially be used by an attacker to gain insights into the internal workings of the application, which they could then exploit.

The updated code fixes this vulnerability by removing the line that returned the exception details to the user. Instead, it now logs these details using a hypothetical Log.Error method. This allows developers to still access this information for debugging purposes, but keeps it hidden from users.

In addition, the updated code returns a generic error message to the user whenever an exception occurs. This message does not reveal any sensitive technical information, making it safe to display.

This is a simple example of how to handle exceptions in a more secure manner. In a real-world application, you would likely want to use a more sophisticated error handling and logging system. This might involve using middleware or filters to handle exceptions in a centralized manner, as well as more detailed logging mechanisms.

References