HIGH data exposureaspnetcsharp

Data Exposure in Aspnet (Csharp)

Data Exposure in Aspnet with Csharp — how this specific combination creates or exposes the vulnerability

Data exposure in ASP.NET applications written in C# commonly occurs when sensitive information such as connection strings, API keys, personal identifiable information (PII), or session data is unintentionally returned in HTTP responses, logged in plain text, or transmitted without adequate protection. In ASP.NET, whether using traditional MVC, Web API, or minimal APIs, C# code controls how data is serialized, cached, and sent to clients. A typical root cause is improper access control or serialization configuration that exposes internal objects or debug details to unauthenticated users.

For example, an endpoint that returns a user object may inadvertently include password hashes or internal identifiers if the serialization settings are too permissive. In ASP.NET Core, the default JSON serializer (System.Text.Json) may include public fields or properties that should remain hidden. Without explicit filtering or view models, sensitive data can leak through responses. This risk is heightened when response types are not carefully constrained, or when developers rely on dynamic objects or reflection-based serialization that expose more than intended.

Another common scenario involves diagnostic or debug endpoints left enabled in non-production environments. These can return stack traces, configuration details, or in-memory state, revealing paths, environment variables, or secrets. Even when using OpenAPI/Swagger, if the server does not enforce strict schema validation and response filtering, the runtime behavior may diverge from the documented contract, exposing fields not described in the spec.

Data exposure can also stem from insecure caching headers or misconfigured middleware that allows sensitive responses to be stored in browser caches or intermediate proxies. In C#, developers must explicitly set cache policies and avoid caching responses that contain private data. Without proper [ResponseCache] attributes or custom middleware that sets no-store headers, sensitive information may persist in caches longer than intended.

When scanning such applications with middleBrick, the tool performs black-box testing against the unauthenticated attack surface, checking whether endpoints return sensitive data such as keys, PII, or error details. It cross-references the OpenAPI/Swagger specification (including $ref resolution) with runtime responses to detect mismatches and unintended data exposure across all 12 security checks, including Data Exposure and Property Authorization.

Csharp-Specific Remediation in Aspnet — concrete code fixes

To remediate data exposure in ASP.NET with C#, apply precise controls over serialization, response shaping, and caching. Prefer view models or DTOs (Data Transfer Objects) that expose only necessary fields, and avoid returning domain entities directly. Use attributes from System.Text.Json to control serialization behavior explicitly.

Example 1: Using DTOs and explicit serialization settings

using Microsoft.AspNetCore.Mvc;
using System.Text.Json.Serialization;

namespace SecureApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class UsersController : ControllerBase
    {
        private readonly AppDbContext _context;

        public UsersController(AppDbContext context)
        {
            _context = context;
        }

        [HttpGet("{id}")]
        public IActionResult GetUser(int id)
        {
            var user = _context.Users.Find(id);
            if (user == null) return NotFound();

            var dto = new UserDto
            {
                Id = user.Id,
                Username = user.Username,
                Email = user.Email
                // Do not include PasswordHash, InternalId, or other sensitive fields
            };

            return Ok(dto);
        }
    }

    public class UserDto
    {
        public int Id { get; set; }
        public string Username { get; set; } = string.Empty;
        public string Email { get; set; } = string.Empty;

        [JsonIgnore]
        public string PasswordHash { get; set; } = string.Empty;
    }
}

Example 2: Configuring System.Text.Json to ignore sensitive properties globally

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Text.Json;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

// Configure JSON options to ignore fields with [JsonIgnore] and use camelCase
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
        // Sensitive properties marked with [JsonIgnore] are omitted automatically
    });

var app = builder.Build();
app.UseHttpsRedirection();
app.MapControllers();
app.Run();

Example 3: Preventing caching of sensitive responses

using Microsoft.AspNetCore.Mvc;

namespace SecureApi.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProfileController : ControllerBase
    {
        [HttpGet]
        [ResponseCache(NoStore = true, Duration = 0)]
        public IActionResult GetCurrentProfile()
        {
            var profile = new
            {
                UserId = 1,
                DisplayName = "Alice",
                Ssn = "123-45-6789" // Sensitive — should not be cached
            };
            return Ok(profile);
        }
    }
}

Example 4: Securing OpenAPI generation to exclude sensitive properties

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

// In Program.cs or Startup.cs
builder.Services.AddSwaggerGen(c =>
{
    c.SchemaFilter();
});

public class ExcludeSensitivePropertiesSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type == typeof(User))
        {
            // Remove sensitive properties from the schema to prevent accidental documentation
            var propertiesToRemove = new[] { "PasswordHash", "InternalId" };
            foreach (var prop in propertiesToRemove)
            {
                schema.Properties?.Remove(prop);
            }
        }
    }
}

These practices ensure that only intended data is serialized and returned, reducing the risk of data exposure. middleBrick validates such configurations by analyzing endpoint responses against the defined schema and runtime behavior, flagging unintended data leakage across checks like Data Exposure and Property Authorization.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Can Data Exposure be caused by incorrect JSON serialization settings in C#?
Yes. Overly permissive serialization (e.g., exposing public fields or omitting [JsonIgnore]) can cause sensitive fields to appear in API responses. Use DTOs and explicit serialization settings to limit exposed data.
Does middleBrick detect Data Exposure in unauthenticated scans of ASP.NET endpoints?
Yes. middleBrick tests the unauthenticated attack surface and cross-references OpenAPI specs with runtime responses to identify unintended data exposure without requiring credentials.