Excessive Data Exposure in Aspnet with Bearer Tokens
Excessive Data Exposure in Aspnet with Bearer Tokens — how this specific combination creates or exposes the vulnerability
Excessive Data Exposure occurs when an API returns more information than necessary for a given operation, and in ASP.NET APIs using Bearer Tokens this often intersects with authentication and authorization misconfigurations. A typical pattern is an endpoint that accepts a Bearer Token for authentication but then returns full database entities, including sensitive fields such as passwords, internal identifiers, or PII, because the response model mirrors the domain model directly.
In ASP.NET Core, if controller actions serialize entities with Newtonsoft.Json or System.Text.Json without explicit projection, fields like User.PasswordHash or User.TwoFactorSecret can be included in JSON responses. Because Bearer Tokens are often stored in browser local storage or mobile secure storage, a compromised token can lead to significant data leakage if responses are overly permissive. Attackers may exploit Insecure Direct Object References (IDOR) or Broken Object Level Authorization (BOLA) to manipulate identifiers and enumerate records, combining this with excessive data exposure to harvest sensitive information across user boundaries.
For example, an endpoint like GET /api/users/{id} might return the complete user record including password hashes, password reset tokens, or internal status flags. Even when Bearer Token validation succeeds, the lack of field-level authorization allows any authenticated user to see other users’ sensitive data if they guess or iterate IDs. This is commonly seen in APIs that skip view models or DTOs and bind directly to EF entities, inadvertently leaking columns that should remain server-side only.
The issue is compounded when APIs do not enforce consistent authorization checks across related resources. An attacker with a valid Bearer Token might access /api/users/{id}/details and receive nested objects containing role assignments, permissions, or audit logs that should be restricted to administrators. Because ASP.NET’s default JSON serializers are permissive, developers must explicitly define what is serialized and ensure that tokens do not grant broader visibility than intended.
Another vector involves logging and error messages. If an ASP.NET API configured to use Bearer Tokens inadvertently includes full request or response bodies in logs, sensitive data such as tokens or PII can be persisted or exposed through log aggregation systems. This creates a secondary exposure path where data is not only returned to clients but also stored in locations with weaker access controls.
To detect this during a scan, middleBrick runs checks that compare OpenAPI/Swagger spec definitions with runtime responses, identifying fields returned that are not documented or that should be restricted based on scope and role. This approach is valuable because it highlights mismatches between declared behavior and actual data exposure without requiring access to source code, focusing on the observable API surface used with Bearer Tokens.
Bearer Tokens-Specific Remediation in Aspnet — concrete code fixes
Remediation centers on minimizing data exposure through explicit serialization control, strict authorization, and secure handling of Bearer Tokens in ASP.NET APIs. Below are concrete code examples that demonstrate secure patterns.
1. Use DTOs and Explicit Projection
Define Data Transfer Objects (DTOs) that include only the fields required by the client. Use projection via LINQ or mapping libraries to avoid serializing sensitive properties.
// User DTO with only safe fields
public class UserProfileDto
{
public Guid Id { get; set; }
public string Email { get; set; }
public string Name { get; set; }
}
// Controller action returning DTO
[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
private readonly AppDbContext _context;
private readonly IMapper _mapper; // AutoMapper configured
public UsersController(AppDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
[HttpGet("{id:guid}")]
public async Task<ActionResult<UserProfileDto>> GetUserById(Guid id)
{
var user = await _context.Users
.Where(u => u.Id == id)
.Select(u => _mapper.Map<UserProfileDto>(u))
.FirstOrDefaultAsync();
if (user == null)
{
return NotFound();
}
return Ok(user);
}
}
2. Configure JSON Serialization to Ignore Sensitive Properties
Ensure that System.Text.Json or Newtonsoft.Json settings exclude sensitive fields by default. For System.Text.Json, use [JsonIgnore] or configure property naming policies.
// Using System.Text.Json with JsonIgnore
public class User
{
public Guid Id { get; set; }
public string Email { get; set; }
public string Name { get; set; }
[JsonIgnore]
public string PasswordHash { get; set; }
[JsonIgnore]
public string PasswordResetToken { get; set; }
}
// In Program.cs or Startup.cs
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
3. Enforce Authorization at the Resource Level
Use policy-based authorization and ensure that every endpoint verifies ownership or role before returning data. Combine Bearer Token validation with resource-based checks.
[Authorize(AuthenticationSchemes = "Bearer")]
[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
private readonly AppDbContext _context;
public UsersController(AppDbContext context)
{
_context = context;
}
[HttpGet("{id:guid}")]
public async Task<ActionResult<UserProfileDto>> GetUser(Guid id)
{
var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (userIdClaim == null || Guid.Parse(userIdClaim) != id)
{
return Forbid();
}
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound();
}
var dto = new UserProfileDto
{
Id = user.Id,
Email = user.Email,
Name = user.Name
};
return Ok(dto);
}
}
4. Secure Bearer Token Handling and Logging
Avoid logging request or response bodies when using Bearer Tokens. If logging is necessary, sanitize tokens and sensitive fields.
// Example of sanitized logging in middleware
app.Use(async (context, next) =>
{
// Do not log Authorization header value directly
var authHeader = context.Request.Headers["Authorization"].ToString();
// Proceed without exposing token in logs
await next();
});
5. Apply Scopes and Minimize Token Permissions
Design token scopes to limit what data a token can access. Validate scopes in API actions to ensure least privilege.
Related CWEs: propertyAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-915 | Mass Assignment | HIGH |