Cross Site Request Forgery in Aspnet with Bearer Tokens
Cross Site Request Forgery in Aspnet with Bearer Tokens
Cross Site Request Forgery (CSRF) in ASP.NET applications using Bearer tokens is a nuanced risk that depends on how tokens are issued, stored, and transmitted. While Bearer tokens are typically designed for stateless, out-of-band authentication (e.g., via Authorization headers), CSRF remains relevant when tokens are inadvertently exposed to browser contexts or mixed with cookie-based flows.
CSRF relies on the browser automatically including credentials with cross-origin requests. For traditional cookie-based sessions, frameworks like ASP.NET provide anti-forgery tokens (e.g., ValidateAntiForgeryToken). When using Bearer tokens in pure API scenarios—sent via the Authorization header—browsers do not automatically include them in cross-origin requests, which mitigates CSRF. However, vulnerabilities arise when Bearer tokens are stored in cookies, local storage with JavaScript exposure, or when token handling logic is inconsistent across endpoints.
ASP.NET applications that accept Bearer tokens via cookies (for hybrid API/web clients) or through insecure storage may expose endpoints to CSRF. For example, if a token is stored in a cookie without the SameSite=Strict or Secure attributes, or if JavaScript can read the token (e.g., via localStorage and included in headers), an attacker can craft malicious cross-origin requests that the browser executes while the user is authenticated.
Consider an ASP.NET Core Web API that uses Bearer tokens but also serves UI views. If the token is embedded in a page (e.g., in a JavaScript variable or cookie) and no anti-forgery mechanism is applied to state-changing endpoints, a malicious site can trigger actions on behalf of the user. Real-world patterns include OAuth misconfigurations where access tokens are passed as query parameters or stored insecurely, enabling token leakage via logs or referrer headers.
Specific attack scenarios include a user authenticated to an ASP.NET endpoint with a Bearer token stored in a cookie. An attacker hosts a malicious page that issues a POST request to the vulnerable endpoint. The browser includes the cookie (and thus the token) automatically, leading to unauthorized actions. This is particularly critical in endpoints that change state (e.g., POST /transfer) without requiring re-authentication or additional validation.
To contextualize, middleBrick scans for such inconsistencies during its 12 parallel checks, including Authentication, BOLA/IDOR, and Unsafe Consumption. The scanner cross-references OpenAPI/Swagger specs (2.0, 3.0, 3.1) with runtime behavior to detect exposed tokens or missing protections, ensuring findings align with OWASP API Top 10 and related compliance frameworks.
Bearer Tokens-Specific Remediation in Aspnet
Remediation for CSRF in ASP.NET with Bearer tokens focuses on ensuring tokens are handled securely and that endpoints validate the origin of requests. Below are concrete fixes and code examples.
1. Use Authorization Header Only
Ensure Bearer tokens are sent exclusively via the Authorization: Bearer <token> header and never stored in cookies accessible to JavaScript. Configure CORS and authentication to reject cookie-based token transmission.
// Program.cs in ASP.NET Core
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://your-issuer.com",
ValidAudience = "https://your-audience.com",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-very-secure-key-here-ensure-length"))
};
// Prevent cookies from being used to carry tokens
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Headers["Authorization"].ToString()?.Replace("Bearer ", "");
return Task.CompletedTask;
}
};
});
2. Enforce Anti-Forgery for Hybrid Flows
If your application mixes cookies and tokens (e.g., for web UI + API), apply anti-forgery validation to endpoints that accept state-changing requests. Use ValidateAntiForgeryToken alongside Bearer validation.
[ApiController]
[Route("api/[controller]")]
public class TransferController : ControllerBase
{
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public IActionResult Transfer([FromBody] TransferRequest request)
{
// Action logic
return Ok();
}
}
3. Set Secure Cookie Attributes if Used
If tokens must be stored in cookies (e.g., for legacy support), enforce SameSite=Strict, Secure, and HttpOnly to mitigate CSRF and XSS risks.
// In ConfigureServices
services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.Strict;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.HttpOnly = true;
});
4. Validate Origin and Referer Headers
Add middleware to reject requests with suspicious origins. This complements token validation and helps block cross-origin attacks.
app.Use(async (context, next) =>
{
var allowedOrigins = new[] { "https://your-trusted-domain.com" };
var origin = context.Request.Headers["Origin"].ToString();
var referer = context.Request.Headers["Referer"].ToString();
if (!string.IsNullOrEmpty(origin) && !allowedOrigins.Contains(origin))
{
context.Response.StatusCode = 403;
return;
}
// Optional: validate referer similarly
await next();
});
5. Avoid Token Leakage in Logs and URLs
Ensure tokens are not logged or passed in URLs. Use headers only and sanitize logging pipelines.
// Example: Exclude Authorization header from logging
builder.Logging.AddFilter("Microsoft.AspNetCore.HttpLogging", LogLevel.Warning);
middleBrick’s scans include checks for insecure token handling and missing anti-forgery measures. By aligning with these remediation steps, applications reduce CSRF risk while maintaining compatibility with Bearer token flows.