HIGH cross site request forgeryaspnetbasic auth

Cross Site Request Forgery in Aspnet with Basic Auth

Cross Site Request Forgery in Aspnet with Basic Auth

Cross Site Request Forgery (CSRF) in ASP.NET when using Basic Authentication creates a scenario where authenticated requests can be forged by malicious sites. With Basic Auth, credentials are typically sent in the Authorization header on each request. If the application relies solely on header-based authentication without anti-forgery tokens or proper SameSite cookie policies, a browser automatically including those headers (e.g., via cached credentials) can cause the server to process state-changing requests originating from untrusted origins.

ASP.NET’s default behavior for cookie authentication and session management can inadvertently enable CSRF when Basic Auth is used in a mixed context—for example, when cookies are also present for the same domain. An attacker can craft a form on a malicious site that performs a state-changing HTTP method like POST, PUT, or DELETE to your ASP.NET endpoint. Because the browser attaches the Basic Auth credentials automatically as part of the request headers, the server may treat the forged request as legitimate, especially if it does not validate the Origin or Referer headers and does not enforce anti-CSRF measures for non-browser clients or APIs consumed by embedded contexts.

Consider an ASP.NET Core controller that accepts money transfers via a POST endpoint and relies on Basic Auth for identity. An attacker can host an image tag or a form with JavaScript that submits a request to that endpoint. Even though Basic Auth transmits credentials in headers, the browser may include them if the endpoint is on the same domain or if CORS is misconfigured to allow credentials. Without a request verification mechanism, the server processes the transaction based solely on the presence of valid credentials, not on a cryptographically signed token that proves the request was intentionally initiated by the client.

The risk is compounded when endpoints accept JSON payloads and do not validate the Content-Type header strictly, enabling an attacker to leverage JSON-based formats to inject malicious requests. CSRF against Basic Auth–protected endpoints does not require stealing the credentials; it exploits the browser’s automatic credential attachment and the application’s lack of origin-bound request validation. Proper mitigation involves synchronizer token patterns, SameSite cookie attributes, and strict CORS configurations that disallow credentials from untrusted origins.

Basic Auth-Specific Remediation in Aspnet

To secure ASP.NET applications using Basic Authentication against CSRF, implement anti-forgery tokens for state-changing operations and enforce strict CORS policies. For API-style endpoints, validate the Origin and Referer headers where feasible and avoid relying solely on header-based authentication for browser-facing interactions. Below are concrete remediation steps with code examples.

1. Anti-Forgery Tokens for MVC and Razor Pages

In ASP.NET Core MVC, enable and validate anti-forgery tokens for POST actions. This ensures that requests must contain a valid token tied to the user’s session, preventing forged requests from external sites.

// In Startup.cs or Program.cs
services.AddAntiforgery(options =>
{
    options.HeaderName = "X-CSRF-TOKEN";
});

// In a controller
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Transfer([FromForm] TransferModel model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(model);
    }
    // Process transfer
    return Ok();
}

// In the view, include the token:
<form method="post">
    <input name="amount" type="number" />
    <input name="destinationAccount" type="text" />
    <input name="__RequestVerificationToken" value="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" />
    <button type="submit">Transfer</button>
</form>

2. CORS Configuration to Restrict Credentials

Configure CORS to disallow credentials from untrusted origins. This prevents browsers from sending Basic Auth headers to malicious sites that may trick users into submitting requests.

// In Program.cs
builder.Services.AddCors(options =>
{
    options.AddPolicy("SecurePolicy", policy =>
    {
        policy.WithOrigins("https://trusted.example.com")
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // Only allow trusted origins to send credentials
    });
});

app.UseCors("SecurePolicy");

3. Validate Origin and Referer Headers for Sensitive Actions

For endpoints that are primarily API-based but still used in browser contexts, add middleware or action filters to validate the Origin or Referer header for non-GET requests.

// Example middleware snippet
app.Use(async (context, next) =>
{
    if (context.Request.Method == "POST" || context.Request.Method == "PUT" || context.Request.Method == "DELETE")
    {
        var origin = context.Request.Headers["Origin"].ToString();
        var referer = context.Request.Headers["Referer"].ToString();
        if (!IsValidOrigin(origin) && !IsValidReferer(referer))
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Forbidden");
            return;
        }
    }
    await next.Invoke();
});

bool IsValidOrigin(string origin)
{
    var allowed = new[] { "https://trusted.example.com" };
    return allowed.Contains(origin);
}

bool IsValidReferer(string referer)
{
    var allowed = new[] { "https://trusted.example.com" };
    return allowed.Contains(referer);
}

4. Use SameSite Cookie Attributes

If your application uses cookies alongside Basic Auth (e.g., for session management), set SameSite=Strict or SameSite=Lax to prevent browsers from sending cookies in cross-site requests.

// In cookie policy configuration
app.UseCookiePolicy(new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict
});

5. Avoid Sending Credentials in URLs

Ensure Basic Auth credentials are transmitted only via the Authorization header and never embedded in URLs, which can be leaked in logs, Referer headers, or browser history.

// Correct: Authorization header
var client = new HttpClient();
var byteArray = Encoding.ASCII.GetBytes($"{username}:{password}");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

// Incorrect: credentials in URL
// var client = new HttpClient();
// client.BaseAddress = new Uri("https://api.example.com/endpoint?user=alice&pass=secret");

Frequently Asked Questions

Can CSRF occur with Basic Auth if the API is consumed by a single-page application?
Yes. If a SPA stores Basic Auth credentials in localStorage and adds them to headers, malicious scripts on other sites can trigger requests that the browser sends with those headers. Use anti-forgery tokens or OAuth-based flows with short-lived tokens instead.
Does enabling CORS with credentials fully protect against CSRF in ASP.NET?
No. CORS with credentials controls which origins can send requests, but it does not prevent CSRF if a trusted origin is compromised. Always pair CORS with anti-forgery validation for state-changing operations.