Skip to main content

Technical information leak - Errors

Need

Prevention of technical information leaks through error messages

Context

  • Usage of C# for building robust and scalable applications
  • Usage of System for low-level operations and interactions with the operating system
  • Usage of Microsoft.AspNetCore.Mvc for building web applications with ASP.NET Core

Description

Non compliant code

using System;
using Microsoft.AspNetCore.Mvc;

namespace VulnerableApp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class VulnerableController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
try
{
// Some code here...
}
catch (Exception ex)
{
return BadRequest(new { message = ex.Message, stackTrace = ex.StackTrace });
}
}

[HttpPost]
public IActionResult Post([FromBody] string value)
{
try
{
// Some code here...
}
catch (Exception ex)
{
return BadRequest(new { message = ex.Message, stackTrace = ex.StackTrace });
}
}
}
}

The above code is a simple ASP.NET Core controller with two endpoints (GET and POST). These endpoints are vulnerable to technical information leakage through error messages.

In both endpoints, the developer has implemented a try-catch block to handle exceptions. However, in the catch block, the developer is returning the exception message and stack trace to the client in the response.

This is a security vulnerability because it leaks potentially sensitive technical information to the client. An attacker can use this information to understand the underlying code structure, logic, and potentially discover other vulnerabilities to exploit.

For example, an attacker can send massive requests to the endpoint or send massive characters in the body of the application to cause the server to throw errors. The server will then return detailed error information, including the stack trace, which can provide the attacker with valuable insights into the application's inner workings.

Steps

  • Remove the try-catch blocks in the Get and Post methods.
  • Implement proper error handling and logging mechanisms in the application.
  • Use appropriate status codes and error messages in the response instead of returning the exception details.
  • Implement input validation and sanitization to prevent malicious input from causing errors.
  • Consider implementing rate limiting or throttling mechanisms to prevent abuse of the endpoints.
  • Regularly update and patch the application and its dependencies to address any known security vulnerabilities.

Compliant code

using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace VulnerableApp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class VulnerableController : ControllerBase
{
private readonly ILogger<VulnerableController> _logger;

public VulnerableController(ILogger<VulnerableController> logger)
{
_logger = logger;
}

[HttpGet]
public IActionResult Get()
{
// Some code here...
return Ok();
}

[HttpPost]
public IActionResult Post([FromBody] string value)
{
// Validate and sanitize input
if (string.IsNullOrEmpty(value) || value.Length > 1000)
{
return BadRequest("Invalid input");
}

// Some code here...
return Ok();
}
}
}

The updated code removes the try-catch blocks in the Get and Post methods. Instead of catching exceptions and returning their details in the response, the application now lets any unhandled exceptions propagate up the call stack. This prevents the leakage of technical information that could be useful to an attacker.

The ILogger interface is used to log any exceptions or errors that occur. This allows developers to monitor and troubleshoot issues without exposing sensitive information to the client.

The Post method now includes input validation and sanitization. If the input is null, empty, or excessively long, the method returns a BadRequest response with a generic error message. This prevents malicious input from causing errors or exceptions.

The code does not include rate limiting or throttling mechanisms, as these would typically be implemented at a higher level (e.g., in middleware or at the network level). However, these are important considerations for preventing abuse of the endpoints.

Finally, it's important to regularly update and patch the application and its dependencies to address any known security vulnerabilities. This is not reflected in the code, but is a crucial part of maintaining a secure application.

References