Missing Tls in Aspnet with Mutual Tls
Missing Tls in Aspnet with Mutual Tls — how this specific combination creates or exposes the vulnerability
When an ASP.NET API is configured to require client certificates (mutual TLS) but fails to enforce transport layer security (TLS) at the server level, the channel between client and server can be downgraded or intercepted. This specific combination—expecting client certificates while the server listens without enforced TLS—creates a scenario where authentication based on certificates is undermined by an unencrypted or weakly encrypted path.
Mutual TLS relies on both parties proving identity through certificates over a cryptographically secured channel. If the server does not require and enforce TLS, an attacker positioned on the network may be able to redirect or manipulate traffic before it reaches the point where client certificate validation occurs. For example, a request could be intercepted in plaintext or routed to a malicious endpoint that terminates TLS independently, bypassing the intended mutual authentication boundary. In ASP.NET applications, this can happen when development settings or misconfigured IIS/Kestrel endpoints allow HTTP alongside HTTPS, or when the server’s certificate bindings do not mandate TLS for all listener endpoints.
Additionally, improper certificate validation in the server can compound the issue. If the server validates client certificates but does so after accepting connections over non-TLS transports, the client certificate may be exposed in cleartext or subject to tampering during initial negotiation phases. Attackers can exploit this by forcing a client to send its certificate over an unencrypted path, then replaying or modifying it. Common missteps include binding certificates to HTTP.sys or Kestrel without corresponding HTTPS enforcement, or using development profiles that disable HTTPS during debugging but remain active in environments where they should be disabled entirely.
Another vector specific to ASP.NET involves the use of HTTP.sys or IIS with mismatched bindings. For instance, a site might listen on port 80 for certain paths while expecting client certs only on port 443. If routing rules or reverse proxies direct traffic to the non-TLS port, the mutual TLS assurance is effectively nullified. OWASP API Security Top 10 categories such as Security Misconfiguration and Broken Object Level Authorization can intersect here when unauthenticated or weakly authenticated paths expose endpoints that should be protected by both transport and certificate checks.
To detect such issues, scanning tools evaluate whether server endpoints enforce TLS before any sensitive authentication handshake, including client certificate exchange. They also check whether certificate validation logic is consistently applied across all routes and whether insecure configurations remain reachable. This ensures that the mutual TLS setup is not only present in code or deployment artifacts but is actually enforced at the network and application layer for every request path.
Mutual Tls-Specific Remediation in Aspnet — concrete code fixes
Remediation centers on enforcing HTTPS across all endpoints and ensuring that client certificate validation is applied before any business logic processes the request. Below are concrete configurations and code examples for ASP.NET Core that demonstrate how to require TLS and validate client certificates robustly.
Enforce HTTPS and Require Client Certificates in Program.cs
var builder = WebApplication.CreateBuilder(args);
// Require HTTPS redirection for all requests
builder.Services.Configure(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
// Add authentication with certificate requirements
builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.AllowedCertificateTypes = CertificateTypes.All;
options.RevocationMode = X509RevocationMode.Online;
options.ValidationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
// Validate thumbprint, subject, or other custom logic
var allowedThumbprint = "A1B2C3D4E5F6...";
if (context.ClientCertificate?.Thumbprint != allowedThumbprint)
{
context.Fail("Invalid certificate thumbprint.");
}
return Task.CompletedTask;
}
};
});
builder.Services.AddAuthorization();
var app = builder.Build();
// Enforce HTTPS for all endpoints
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/secure", () => "Mutual TLS verified");
app.Run();
Kestrel Server Configuration with Mutual TLS
Configure Kestrel in appsettings.json to require HTTPS and client certificates:
{
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
},
"Endpoints": {
"Https": {
"Url": "https://0.0.0.0:5001",
"Protocols": "Http2",
"Certificate": {
"Path": "path/to/server.pfx",
"Password": "server-password"
},
"ClientCertificateMode": "RequireCertificate",
"AllowedClients": [ "192.168.1.100" ]
}
}
}
}
With this configuration, Kestrel will reject connections that do not present a valid client certificate and will enforce TLS 1.2 or higher depending on system settings. The AllowedClients filter provides an additional layer by IP, though certificate validation remains the primary authentication mechanism.
IIS or HTTP.sys Integration
When hosting behind IIS or using HTTP.sys directly, ensure that the applicationHost.config or equivalent binding settings require SSL and client certificates. In web.config, set sslFlags to require both client certificates and SSL:
<system.webServer>
<security>
<access sslFlags="Ssl, SslNegotiateCert" />
</security>
<authentication>
<clientCertificateMappingAuthentication enabled="true">
<clear />
</clientCertificateMappingAuthentication>
</authentication>
</system.webServer>
Ensure that the server certificate is correctly installed in the local machine store and that the binding includes the correct IP and port. This setup complements the ASP.NET Core authentication logic by enforcing TLS and client certificate requirements at the reverse proxy or host level before requests reach the application pipeline.
Validation and Testing
After applying these configurations, test using a client that presents a valid certificate and verify that requests without TLS or without a valid client certificate are rejected. Use tools like curl with --cert and --key to simulate mutual TLS, and confirm that endpoints do not respond over plain HTTP. Continuous monitoring and scanning help ensure that future changes do not inadvertently reintroduce insecure bindings.
Related CWEs: encryption
| CWE ID | Name | Severity |
|---|---|---|
| CWE-319 | Cleartext Transmission of Sensitive Information | HIGH |
| CWE-295 | Improper Certificate Validation | HIGH |
| CWE-326 | Inadequate Encryption Strength | HIGH |
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm | HIGH |
| CWE-328 | Use of Weak Hash | HIGH |
| CWE-330 | Use of Insufficiently Random Values | HIGH |
| CWE-338 | Use of Cryptographically Weak PRNG | MEDIUM |
| CWE-693 | Protection Mechanism Failure | MEDIUM |
| CWE-757 | Selection of Less-Secure Algorithm During Negotiation | HIGH |
| CWE-261 | Weak Encoding for Password | HIGH |