HIGH information disclosureaspnet

Information Disclosure in Aspnet

How Information Disclosure Manifests in Aspnet

Information disclosure in Aspnet applications often stems from improper configuration and default behaviors that expose sensitive data. The framework's verbose error messages and diagnostic features, while helpful during development, become significant security liabilities in production.

Aspnet's default exception handling is particularly problematic. When an unhandled exception occurs, the framework generates detailed error pages containing stack traces, source file paths, and environment information. Consider this common pattern:

public IActionResult GetUserData(int id)
{
    try
    {
        var user = _userService.GetById(id);
        return Ok(user);
    }
    catch (Exception ex)
    {
        // Exposing raw exception details
        return StatusCode(500, ex.Message);
    }
}

This code directly returns exception messages to clients, potentially revealing database schemas, connection strings, or internal logic. An attacker could trigger specific exceptions to map the application's structure.

Another Aspnet-specific disclosure vector involves model binding errors. When complex types fail to bind, Aspnet generates detailed error responses:

public IActionResult CreateUser([FromBody] UserCreateModel model)
{
    if (!ModelState.IsValid)
    {
        // Returns detailed model state with property names
        return BadRequest(ModelState);
    }
}

Attackers can exploit this to discover API contract details, field names, and validation rules. The response might reveal whether a field exists, its expected format, and even business logic constraints.

Aspnet's XML documentation and help pages present another disclosure risk. When enabled in production, these features expose method signatures, parameter descriptions, and sometimes implementation details:

// Exposed via XML docs in production
/// <summary>
/// Retrieves user by ID from SQL Server database
/// </summary>
/// <param name="userId">User identifier</param>
/// <returns>User data object</returns>
public IActionResult GetUser(int userId)
{
    // Implementation
}

Directory browsing is another Aspnet-specific issue. If not explicitly disabled, attackers can enumerate application files and directories, discovering API endpoints, configuration files, and sensitive resources.

Aspnet-Specific Detection

Detecting information disclosure in Aspnet applications requires examining both configuration and runtime behavior. Start by scanning your application's configuration files for sensitive data exposure:

# Check for exposed secrets in configuration
cat appsettings.json | grep -E "(password|key|secret|token)" -A 2 -B 2

# Verify production settings
cat appsettings.Production.json

middleBrick's Aspnet-specific scanning identifies several disclosure patterns automatically. The scanner examines your application's HTTP responses for verbose error details, model state disclosures, and stack traces. It also tests for common Aspnet endpoints that might leak information:

# Scan with middleBrick CLI
middlebrick scan https://yourapi.com/api/users

# Output includes:
# - Error response analysis (stack traces, exception details)
# - Model state disclosure detection
# - Configuration exposure checks
# - Directory browsing vulnerability assessment

The scanner specifically looks for Aspnet's default diagnostic endpoints like:

  • /error - Detailed error pages
  • /swagger - API documentation (if exposed in production)
  • /health - Health check endpoints revealing system details
  • /metrics - Performance metrics with sensitive data

middleBrick also tests for Aspnet Core's developer exception page exposure in production environments. This occurs when ASPNETCORE_ENVIRONMENT isn't properly set or when UseDeveloperExceptionPage() is accidentally called in production code paths.

Runtime monitoring complements static analysis. Tools like Application Insights or custom middleware can detect when sensitive information is being logged or returned in responses. Here's a middleware example for detection:

public class InformationDisclosureMiddleware
{
    private readonly RequestDelegate _next;
    private static readonly HashSet<string> SensitiveKeywords = 
        new() { "password", "secret", "key", "token", "connectionstring" };

    public InformationDisclosureMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var originalBodyStream = context.Response.Body;
        
        using (var responseBody = new MemoryStream())
        {
            context.Response.Body = responseBody;
            
            await _next(context);
            
            context.Response.Body.Seek(0, SeekOrigin.Begin);
            var bodyText = await new StreamReader(context.Response.Body).ReadToEndAsync();
            
            // Check for sensitive information in response
            if (SensitiveKeywords.Any(bodyText.ToLower().Contains))
            {
                // Log or alert on potential disclosure
                Console.WriteLine($"Potential information disclosure detected: {context.Request.Path}");
            }
            
            await responseBody.CopyToAsync(originalBodyStream);
        }
    }
}

Aspnet-Specific Remediation

Remediating information disclosure in Aspnet requires both configuration changes and code-level fixes. Start with production environment hardening:

// Program.cs - Production configuration
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Ensure developer exception page is only enabled in development
if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error"); // Custom error page without details
    app.UseHsts();
}

// Disable directory browsing
app.UseDirectoryBrowser(enable: false);

// Remove XML documentation from production builds
app.UseSwagger(); // Remove or protect with authentication
app.UseSwaggerUI(); // Remove or protect with authentication

Implement structured exception handling that avoids information leakage:

public class CustomExceptionHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<CustomExceptionHandlerMiddleware> _logger;

    public CustomExceptionHandlerMiddleware(RequestDelegate next, ILogger<CustomExceptionHandlerMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            // Log full exception details internally
            _logger.LogError(ex, "Unhandled exception at {Path}", context.Request.Path);
            
            // Return generic error response
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = 500;
            
            await context.Response.WriteAsync(JsonSerializer.Serialize(new 
            {
                error = "An unexpected error occurred. Please try again later."
            }));
        }
    }
}

Protect model state responses from information disclosure:

public IActionResult CreateUser([FromBody] UserCreateModel model)
{
    if (!ModelState.IsValid)
    {
        // Return sanitized error response
        var errors = ModelState.Values.SelectMany(v => v.Errors)
            .Select(e => e.ErrorMessage ?? e.Exception?.Message)
            .Where(m => !string.IsNullOrEmpty(m))
            .Distinct()
            .ToList();
            
        return BadRequest(new 
        {
            message = "Validation failed",
            errors = errors.Take(5) // Limit number of errors returned
        });
    }
    
    // Process valid request
    return Ok();
}

Configure Aspnet Core to suppress sensitive information in logs and responses:

// appsettings.Production.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft": "Warning",
      "Microsoft.Hosting": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Security": {
    "HideSensitiveInformation": true,
    "MaxErrorDetails": 0
  }
}

Use Aspnet Core's built-in features for information protection:

// Configure response headers to prevent information disclosure
app.Use(async (context, next) =>
{
    context.Response.OnStarting(() =>
    {
        context.Response.Headers["X-Content-Type-Options"] = "nosniff";
        context.Response.Headers["X-Frame-Options"] = "DENY";
        context.Response.Headers["X-Powered-By"] = ""; // Remove server information
        return Task.CompletedTask;
    });
    
    await next();
});

Frequently Asked Questions

How does middleBrick detect information disclosure in Aspnet applications?
middleBrick performs black-box scanning of your Aspnet API endpoints, testing for verbose error responses, model state disclosures, and configuration exposure. The scanner sends malformed requests to trigger exceptions and analyzes the responses for stack traces, source file paths, and sensitive keywords. It also checks for exposed Swagger documentation, directory browsing, and Aspnet's developer exception page in production environments.
What Aspnet-specific information disclosure risks does middleBrick scan for?
middleBrick scans for Aspnet-specific disclosure vectors including detailed error pages with stack traces, model binding error responses that reveal API contracts, XML documentation exposure, directory browsing vulnerabilities, and health check endpoints that leak system information. The scanner also tests for excessive agency in LLM endpoints and prompt injection vulnerabilities unique to AI-powered Aspnet applications.