HIGH pii leakageaspnetbearer tokens

Pii Leakage in Aspnet with Bearer Tokens

Pii Leakage in Aspnet with Bearer Tokens — how this specific combination creates or exposes the vulnerability

In ASP.NET applications, PII leakage with Bearer Tokens commonly occurs when token handling logic unintentionally exposes sensitive data in logs, error messages, or responses. A typical pattern is storing user identifiers or scopes directly within the token payload or reflecting token details in HTTP responses without proper controls.

Consider an endpoint that returns user profile information and echoes the Authorization header value without redaction:

// Example of vulnerable behavior in an ASP.NET Core controller
[Authorize(AuthenticationSchemes = "Bearer")]
[ApiController]
[Route("[controller]")]
public class ProfileController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var authHeader = Request.Headers["Authorization"].ToString();
        // Vulnerable: including raw token in response
        return Ok(new { User = User.Identity.Name, AuthHeader = authHeader });
    }
}

If this response is logged or cached, the Bearer Token may be stored in plaintext alongside PII such as the username, creating a compound exposure. Attackers who gain access to logs or error reports can recover both the PII and the token, leading to account compromise.

Additionally, misconfigured CORS or HTTP caching can cause tokens and associated PII to be stored in browser history or intermediate caches. For example, if an ASP.NET app sets permissive CORS policies and does not mark responses containing tokens as private, a cached response may be served to unauthorized users, leaking both PII and authentication material.

Another vector involves error handling that includes token details in exception messages. In ASP.NET, unhandled exceptions that surface in development error pages or logs might include the Authorization header value, especially if developers inadvertently include the header in diagnostic strings. This can expose PII bound to the token (such as user ID or email) and the token itself.

Middleware that inspects or enriches requests must also avoid propagating tokens in logs or diagnostics. Even when using standard authentication handlers, custom logging that concatenates user claims with token strings can inadvertently create searchable stores of PII and credentials. These patterns align with common OWASP API Top 10 risks such as excessive data exposure and insufficient logging/monitoring.

Bearer Tokens-Specific Remediation in Aspnet — concrete code fixes

Remediation focuses on ensuring Bearer Tokens are never reflected in responses, logs, or error messages, and that PII is minimized and protected at the application layer.

1. Avoid echoing the Authorization header in responses. Instead, extract only the necessary claims after validating the token:

// Secure pattern: do not return the token; use claims from User
[Authorize(AuthenticationSchemes = "Bearer")]
[ApiController]
[Route("[controller]")]
public class ProfileController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var userId = User.FindFirst("sub")?.Value;
        var email = User.FindFirst("email")?.Value;
        // Return only necessary, consented data
        return Ok(new { UserId = userId, Email = email });
    }
}

2. Configure logging to redact or exclude Authorization headers. In ASP.NET Core, you can filter sensitive headers in diagnostic sources:

// In Program.cs or Startup.cs
builder.Logging.AddFilter("Microsoft.AspNetCore.HttpLogging", LogLevel.Warning);
// Or use a custom filter to scrub headers
app.Use(async (context, next) =>
{
    var originalBody = context.Response.Body;
    try
    {
        await next.Invoke();
    }
    finally
    {
        // Ensure no token is written to logs inadvertently
        // Use structured logging with property filters instead of raw header capture
    }
});

3. Apply data protection and cache-control headers to reduce caching of sensitive responses:

[HttpGet]
[ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
[Authorize(AuthenticationSchemes = "Bearer")]
public IActionResult Get()
{
    // Response will not be stored by shared caches
    return Ok(new { Message = "Private data" });
}

4. Use policy-based authorization to ensure users only access their own data, reducing unnecessary PII exposure in responses:

services.AddAuthorization(options =>
{
    options.AddPolicy("OwnData", policy =>
        policy.RequireAssertion(context =>
            context.User.HasClaim(c => c.Type == "sub") &&
            context.Resource is HttpContext httpContext &&
            httpContext.Request.RouteValues["id"]?.ToString() == context.User.FindFirst("sub")?.Value));
});

5. Rotate and scope tokens appropriately. Short-lived access tokens with limited scopes reduce the impact if PII is inadvertently associated with a token. Store refresh tokens securely server-side and avoid embedding PII in token payloads.

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

Why should I avoid returning the raw Authorization header in API responses?
Returning the raw Authorization header can expose Bearer Tokens and any PII contained in or linked to the token in logs, browser history, or error reports, increasing the risk of credential and identity compromise.
How can I ensure Bearer Tokens are not cached by browsers or intermediaries in ASP.NET?
Use [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] and set appropriate Cache-Control and Pragma headers to prevent caching of responses that include tokens or PII.