Cors Wildcard in Aspnet with Mutual Tls
Cors Wildcard in Aspnet with Mutual Tls — how this specific combination creates or exposes the vulnerability
In ASP.NET, enabling a CORS wildcard while using Mutual TLS (mTLS) can weaken the effective boundary between authenticated clients and authorized origins. With mTLS, the server validates the client certificate, and the client may present a certificate indicating its identity. When WithOrigins("*") is used together with AllowCredentials, browsers are prevented from sending cookies or client certificates to the endpoint; however, non-browser clients or misconfigured HTTP clients can still route requests through the wildcard endpoint. The presence of mTLS does not automatically restrict which origins are allowed once AllowCredentials is set, because CORS policy and transport-layer authentication are not inherently coordinated. If the server uses a permissive CORS policy and relies solely on mTLS for access control, an attacker who can intercept or route traffic to the service might leverage the wildcard to probe for misconfigured mTLS expectations or exploit inconsistent origin checks in middleware. This combination can also complicate logging and audit correlation, because origin information may be absent or overridden by proxies, making it harder to detect abuse tied to specific client identities. The risk is not that mTLS is broken, but that the CORS configuration can expose endpoints to unauthorized cross-origin usage patterns when origin validation is not explicitly aligned with the mTLS trust boundary. For example, if the server uses policy-based authorization that depends on claims from the client certificate but does not restrict origins, a request from an unexpected origin that presents a valid certificate can still succeed, bypassing expected segregation.
Mutual Tls-Specific Remediation in Aspnet — concrete code fixes
Remediation centers on explicit origin validation and strict coordination between CORS and mTLS requirements. Do not use wildcard origins when AllowCredentials is required. Instead, enumerate trusted origins and validate them against certificate metadata when necessary. Below are concrete, syntactically correct examples for ASP.NET Core that demonstrate secure configuration.
mTLS-enabled endpoint with strict CORS policy
Configure Kestrel for client certificate validation and define a CORS policy that references specific origins. Use certificate information for additional authorization decisions when needed.
// Program.cs
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Server.Kestrel.Https;
var builder = WebApplication.CreateBuilder(args);
// Enforce client certificates
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
httpsOptions.ServerCertificate = new X509Certificate2("server.pfx", "password");
httpsOptions.ClientCertificateValidation = (cert, chain, errors) =>
{
if (errors != System.Net.Security.SslPolicyErrors.None)
return false;
// Additional validation: thumbprint, subject, or extended key usage
var allowedThumbprint = "A1B2C3D4E5F6...";
return cert.GetCertHashString().Equals(allowedThumbprint, StringComparison.OrdinalIgnoreCase);
};
});
});
// Define strict origins — do not use WithOrigins("*") when using credentials
builder.Services.AddCors(options =>
{
options.AddPolicy("StrictMtlsPolicy", policy =>
{
policy.WithOrigins(
"https://trusted.example.com",
"https://app.example.org"
)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials(); // Only use if you need to send cookies/auth headers
});
});
var app = builder.Build();
app.UseCors("StrictMtlsPolicy");
// Optionally enforce origin at the handler level when headers are trustworthy
app.Use(async (context, next) =>
{
// Example: correlate certificate subject with allowed origin if forwarded by a trusted proxy
if (context.Request.Headers.TryGetValue("Origin", out var origin))
{
var allowed = new[] { "https://trusted.example.com", "https://app.example.org" };
if (!allowed.Contains(origin))
{
context.Response.StatusCode = 403;
return;
}
}
await next();
});
app.MapGet("/secure", (HttpContext context) =>
{
var cert = context.Connection.ClientCertificate;
return Results.Ok(new { Subject = cert?.Subject, Issuer = cert?.Issuer });
}).RequireAuthorization();
app.Run();
In this setup, CORS is limited to known origins, credentials are only allowed when necessary, and the server validates the client certificate on every connection. If you need to tie authorization to certificate claims, use policy-based authorization:
// Add authorization policy that inspects the client certificate builder.Services.AddAuthorization(options => { options.AddPolicy("RequireSpecificCertificate", policy => { policy.RequireAuthenticatedUser(); policy.RequireAssertion(context => { var cert = context.User.FindFirst(System.Security.Claims.ClaimTypes.Thumbprint)?.Value; return cert != null && cert.Equals("A1B2C3D4E5F6...", StringComparison.OrdinalIgnoreCase); }); }); }); app.UseAuthorization();When using a reverse proxy or load balancer that terminates TLS, ensure the proxy forwards the client certificate or a validated header (e.g., SSL_CLIENT_S_DN) and configure Kestrel to trust that header appropriately. Never disable client certificate validation in production.
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 |