Cors Wildcard in Aspnet with Basic Auth
Cors Wildcard in Aspnet with Basic Auth — how this specific combination creates or exposes the vulnerability
In ASP.NET, a CORS policy that uses a wildcard origin (AllowAnyOrigin) combined with credentialed requests such as HTTP Basic Authentication creates a dangerous configuration. When you set WithOrigins("*") and also enable AllowCredentials(), the browser is required by the CORS specification to reject the response, but many server-side implementations do not enforce this restriction and will still serve responses. This mismatch can lead to credentials being sent cross-origin without proper validation, effectively bypassing intended origin checks.
Basic Authentication transmits credentials in the Authorization header with a base64-encoded token. Even if the server does not process the credentials correctly on the API side, a browser-based client that includes the Authorization header will still send it with the request if CORS allows credentials. A wildcard CORS policy in this context can expose these headers to any origin that knows or guesses the endpoint, increasing the risk of credential leakage in cross-origin scenarios.
Additionally, preflight requests (OPTIONS) will be handled by the server when credentials are present. If the server responds to preflight with a wildcard origin and allows credentials, it signals to the browser that the response is shareable across origins, which is not permitted. This misconfiguration can lead to inconsistent behavior where some browsers block the request while others do not, creating an unpredictable attack surface. Attackers may leverage this inconsistency to craft malicious web pages that make authenticated requests to the API on behalf of a victim user.
Consider an endpoint that returns sensitive user data and uses Basic Auth for access control. If CORS is configured with a wildcard origin and credentials allowed, a compromised site on a different origin can initiate authenticated requests. While the server may enforce authentication, the browser’s CORS policy may not block the response from being read by the attacker’s script, especially if the server incorrectly reflects the Origin header or does not validate against a strict allowlist.
Middleware ordering also plays a role. If CORS middleware is placed after authentication middleware in the pipeline, the request may be authenticated before the CORS policy is evaluated. This can result in authentication headers being processed even for disallowed origins, undermining the intended security boundary. Proper configuration requires both a strict list of origins and careful placement of middleware to ensure CORS checks occur before sensitive processing.
Using tools such as middleBrick’s Scanner can help identify these misconfigurations by testing the unauthenticated attack surface and checking CORS behavior alongside authentication mechanisms. The scanner evaluates headers, preflight responses, and credential handling to highlight risky combinations such as wildcard origins with authentication schemes like Basic Auth.
Basic Auth-Specific Remediation in Aspnet — concrete code fixes
To secure an ASP.NET API using Basic Authentication while avoiding issues with CORS, you must use an explicit list of allowed origins and disable credentials on wildcard configurations. Never use AllowAnyOrigin() together with AllowCredentials(). Instead, define a policy that specifies exact origins and applies only to the endpoints that require authentication.
Below is a correct configuration example using Basic Authentication in ASP.NET Core. This setup ensures that only specified origins can make authenticated requests and that the CORS policy is evaluated before authentication proceeds in a controlled manner.
// Program.cs or Startup.cs
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication("BasicAuthentication")
.AddScheme("BasicAuthentication", null);
builder.Services.AddAuthorization();
// Configure CORS with specific origins and credentials
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOriginsWithAuth", policy =>
{
policy.WithOrigins("https://trusted.example.com", "https://app.example.org")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // Only safe when origins are explicitly listed
});
});
var app = builder.Build();
// Use CORS before authentication and endpoints
app.UseCors("AllowSpecificOriginsWithAuth");
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
Implement the BasicAuthenticationHandler to validate the username and password on each request. This handler should return a 401 status if credentials are missing or invalid, ensuring that unauthorized requests do not proceed further in the pipeline.
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
if (!Request.Headers.ContainsKey("Authorization"))
return AuthenticateResult.Fail("Missing Authorization Header");
var authHeader = Request.Headers["Authorization"].ToString();
if (!authHeader.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
return AuthenticateResult.Fail("Invalid Authorization Header");
var token = authHeader.Substring("Basic ".Length).Trim();
var credentialString = Encoding.UTF8.GetString(Convert.FromBase64String(token));
var credentials = credentialString.Split(':', 2);
var username = credentials[0];
var password = credentials[1];
// Validate credentials against your user store
if (IsValidUser(username, password))
{
var claims = new[] { new Claim(ClaimTypes.Name, username) };
var identity = new ClaimsIdentity(claims, Scheme.Name);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, Scheme.Name);
return AuthenticateResult.Success(ticket);
}
return AuthenticateResult.Fail("Invalid Username or Password");
}
private bool IsValidUser(string username, string password)
{
// Replace with secure user validation logic
return username == "admin" && password == "secure_password_123";
}
}
Ensure that your endpoints requiring authentication are decorated with the [Authorize] attribute and that the CORS policy is applied globally or to specific controllers/actions as needed. Avoid using wildcards when credentials are involved, and always prefer explicit origin allowlists to minimize exposure.
middleBrick’s CLI tool can be used to verify that your configuration does not expose wildcard origins with credentials. By running middlebrick scan <url>, you can detect insecure CORS responses and confirm that authentication mechanisms are not inadvertently exposed to cross-origin requests.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |