Jwt Misconfiguration in Aspnet with Basic Auth
Jwt Misconfiguration in Aspnet with Basic Auth — how this specific combination creates or exposes the vulnerability
Using JWT validation together with HTTP Basic Authentication in an ASP.NET application can introduce subtle misconfigurations that weaken authentication and enable authorization bypasses. When both schemes are enabled without precise policy separation, the runtime may incorrectly select the default authentication handler, allowing access to protected endpoints without a valid JWT or even without any credentials.
A common vulnerability pattern occurs when the JWT bearer scheme is defined but not explicitly set as the default challenge or policy. In such setups, a request that includes only an Authorization: Basic <token> header may be accepted because the authentication middleware falls back to Basic Auth, and authorization filters fail to enforce JWT requirements for specific routes. This can lead to privilege escalation when a low-privilege Basic Auth user gains access to admin or high-scope endpoints that should require a JWT with specific claims or scopes.
Another misconfiguration is binding JWT audiences or issuers too loosely. If the audience validation is omitted or set to a wildcard, an attacker who obtains a valid Basic Auth credential could present a static JWT intended for another service, and ASP.NET may accept it if issuer checks are not strict. Additionally, mixing cookie-based fallback with Basic Auth and JWT can create insecure ordering where an unauthenticated session cookie overrides more secure mechanisms, bypassing JWT validation entirely.
Authorization flaws also arise in policy-based authorization when policies are not explicitly tied to JWT requirements. For example, a controller or action using [Authorize(Policy = "ApiScope")] may not enforce JWT presence if the policy is defined with fallback logic that permits Basic Auth as an alternative. Inconsistent requirement checks across endpoints allow attackers to probe for routes that rely solely on Basic Auth, effectively bypassing JWT-based access controls.
These combinations are particularly risky when endpoints expose sensitive operations or administrative functions. Because Basic Auth transmits credentials in a base64-encoded format without inherent confidentiality, pairing it with JWT without transport encryption or strict scope validation can expose authentication material and enable token substitution attacks. Proper configuration is essential to ensure JWT remains the primary, non-bypassable credential for protected operations.
Basic Auth-Specific Remediation in Aspnet — concrete code fixes
To secure ASP.NET applications that support both JWT and Basic Auth, you must explicitly separate authentication schemes, enforce JWT as the default for API endpoints, and tightly constrain Basic Auth to specific, limited use cases. The following examples demonstrate a secure configuration.
1. Define distinct schemes and set JWT as default
In Program.cs, configure authentication so that JWT is the default challenge and Basic Auth is isolated to a named policy. Avoid using fallback logic that allows Basic Auth to satisfy JWT-required endpoints.
// Program.cs
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = "https://your-identity-provider";
options.Audience = "api1";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://your-identity-provider",
ValidateAudience = true,
ValidateLifetime = true
};
})
.AddBasicAuthentication("basic", "Basic Auth", options >
{
// Validate credentials against a secure store; do not accept weak or default credentials
options.Events = new BasicAuthenticationEvents
{
OnValidateCredentials = context =>
{
var username = context.Username;
var password = context.Password;
// Replace with secure credential validation
if (username == "admin" && password == "S3cureP@ss!")
{
var claims = new[] { new Claim(ClaimTypes.Name, username) };
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
context.Success();
}
else
{
context.Fail("Invalid credentials.");
}
return Task.CompletedTask;
}
};
});
2. Use policy-based authorization to require JWT for sensitive endpoints
Create a policy that mandates JWT presence and specific claims, and apply it to controllers or actions that must not be accessible via Basic Auth alone.
// Program.cs policy definition
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("RequireJwtForAdmin", policy =>
{
policy.RequireAuthenticatedUser();
policy.RequireClaim("scope", "admin:read", "admin:write");
// Optionally require a specific issuer or role claim
policy.RequireClaim("iss", "https://your-identity-provider");
});
});
// Usage in a controller
[ApiController]
[Route("api/admin")]
public class AdminController : ControllerBase
{
[HttpGet("users")]
[Authorize(Policy = "RequireJwtForAdmin")]
public IActionResult GetUsers()
{
return Ok(new[] { "alice", "bob" });
}
}
3. Avoid mixing authentication schemes in the same endpoint pipeline
If Basic Auth is only needed for a limited set of operations (e.g., legacy migration or health probes), isolate it using endpoint routing or a separate route pattern, and do not allow it to serve tokens for JWT-protected routes.
// Program.cs endpoint configuration
app.MapGet("/legacy/health", () => Results.Ok("ok"))
.AllowAnonymous()
.WithMetadata(new ProducesResponseTypeMetadata(typeof(string)));
app.MapGet("/api/data", () => Results.Ok("data"))
.RequireAuthorization()
.RequireAuthorization("RequireJwtForAdmin");
By explicitly separating schemes and enforcing JWT requirements via strict policies, you mitigate the risk of JWT misconfiguration when Basic Auth is present. This approach reduces the attack surface and ensures that sensitive operations remain protected by strong, bearer-only tokens.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |