Arp Spoofing in Aspnet with Mutual Tls
Arp Spoofing in Aspnet with Mutual Tls — how this specific combination creates or exposes the vulnerability
Arp spoofing is a Layer 2 attack where an adversary sends falsified ARP messages to associate their MAC address with the IP of a legitimate host, such as a server or another client. In an ASP.NET application that uses mutual TLS (mTLS) for channel binding, the security model assumes that the TLS session strongly authenticates both peers and protects data in transit. However, mTLS operates at L7 and does not prevent or detect a successful Layer 2 redirection. An attacker on the same broadcast domain can intercept traffic intended for the mTLS-enabled server by spoofing the server’s IP, causing the client to establish an mTLS handshake with the attacker instead of the legitimate server.
When mTLS is used, the client validates the server’s certificate and the server optionally validates the client certificate. If the client resolves the server’s IP via a poisoned ARP cache, the client believes it is talking to the trusted server. The attacker, however, presents their own certificate to the client. If the client does not strictly verify certificate properties or if the attacker presents a valid certificate that the client trusts, the handshake may complete. The attacker can then terminate the mTLS session on one side and establish another mTLS session with the legitimate server, effectively performing a man-in-the-middle (MITM) that mTLS alone cannot detect. This breaks the assumption that the transport identity maps to the intended network endpoint, exposing the application to traffic interception, replay, or manipulation despite the presence of mTLS.
ASP.NET applications that terminate mTLS at the Kestrel server or at a reverse proxy (such as IIS or a load balancer) are vulnerable if the host’s IP-to-MAC bindings are not enforced at the network level. For example, a client using HttpClient with custom ServerCertificateCustomValidationCallback may still proceed if the certificate is valid, even though the underlying TCP flow has been diverted. In cloud or shared-host environments where layer 2 boundaries are less controlled, the risk is elevated. The combination of mTLS with ARP spoofing highlights that application-layer authentication does not substitute for network-layer integrity; without additional controls such as static ARP entries or port-security, an attacker can bypass mTLS by positioning themselves between the client and the legitimate server.
Concrete attack steps in an ASP.NET context include: (1) attacker crafts and floods ARP replies mapping their MAC to the server’s IP; (2) client’s ARP cache updates, pointing to the attacker; (3) client initiates TLS handshake, validates the server certificate, and completes mTLS if the attacker’s certificate is trusted; (4) attacker forwards traffic to the real server after terminating and re-encrypting with the client, enabling eavesdropping or modification. This scenario is particularly dangerous when long-lived sessions and cached credentials are used, as the malicious position can persist across requests. Therefore, defending against this threat requires both network hardening and application-level vigilance, even when strong mTLS configurations are in place.
Mutual Tls-Specific Remediation in Aspnet — concrete code fixes
Remediation focuses on ensuring that the identity established by mTLS is bound to the network path and cannot be trivially subverted by ARP spoofing. Network-level controls such as static ARP entries, port-security, and private VLANs are essential, but application-side practices further reduce risk. Below are concrete code examples for ASP.NET Core that demonstrate robust mTLS configurations and validation logic.
Mutual TLS with Kestrel in ASP.NET Core
Configure Kestrel to require and validate client certificates, and to map the certificate claims to user identity. This ensures that only clients with trusted certificates can establish authenticated sessions.
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.ListenAnyIP(5001, listenOptions =>
{
listenOptions.UseHttps(httpsOptions =>
{
httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
httpsOptions.ServerCertificate = new X509Certificate2("server.pfx", "password");
httpsOptions.ClientCertificateValidation = (cert, chain, errors) =>
{
// Validate certificate chain and policy
if (errors != SslPolicyErrors.None) return false;
// Additional custom checks: thumbprint, subject, enhanced key usage
var allowedThumbprint = "A1B2C3D4E5F6...";
if (cert.GetCertHashString() != allowedThumbprint) return false;
// Ensure the certificate has the client authentication EKU
var eku = cert.Extensions.OfType<X509EnhancedKeyUsageExtension>()
.FirstOrDefault();
if (eku != null && !eku.EnhancedKeyUsages.Cast<Oid>()
.Any(oid => oid.Value == "1.3.6.1.5.5.7.3.2")) // Client Auth EKU
return false;
return true;
};
});
});
});
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapGet("/", () => "Hello over mTLS");
app.Run();
The validation callback performs strict checks: chain validation, thumbprint pinning, and Extended Key Usage for client authentication. This reduces the risk of accepting a certificate presented by an attacker who might be on the other side of a spoofed ARP session.
HttpClient with Server Certificate Validation
When the ASP.NET application acts as a client to another mTLS-protected service, enforce server certificate validation and consider binding the server identity to the expected IP or hostname to prevent redirection to a malicious endpoint.
// Example service client setup
var handler = new SocketsHttpHandler();
handler.SslOptions.RemoteCertificateValidationCallback = (message, cert, chain, errors) =>
{
if (errors != SslPolicyErrors.None) return false;
// Pin to expected thumbprint or validate SAN/IP
var expectedThumbprint = "F6E7D8C9B0A1...";
if (cert.GetCertHashString() != expectedThumbprint) return false;
// Optional: ensure the certificate subject matches the intended service identity
var subject = ((X509Certificate2)cert).Subject;
if (!subject.Contains("CN=expected-service.example.com")) return false;
return true;
};
handler.SslOptions.ClientCertificates ??= new X509CertificateCollection();
handler.SslOptions.ClientCertificates.Add(new X509Certificate2("client.pfx", "password"));
var client = new HttpClient(handler)
{
BaseAddress = new Uri("https://api.example.com")
};
// Use client for authenticated requests
var response = await client.GetAsync("/v1/resource");
By pinning thumbprints and validating the server identity, you reduce the impact of an attacker who might redirect traffic via ARP spoofing but cannot present a certificate that matches the pinned fingerprint or subject.
Defense-in-Depth Recommendations
- Use static ARP entries for critical server endpoints where feasible (e.g., arp -s <server-ip> <server-mac> on the client host).
- Employ port-security on switches to limit MAC addresses per port, mitigating ARP spoofing within the local network.
- Monitor certificate transparency logs and revocation status (OCSP/CRL) to detect unauthorized certificates issued for your domains.
- Combine mTLS with application-level signatures or tokens for critical operations, ensuring that even if a session is intercepted, tampering is detectable.