Skip to content

HCR022

Do not disable server certificate validation.

Why

Assigning ServerCertificateCustomValidationCallback a callback that always returns true — or the HttpClientHandler.DangerousAcceptAnyServerCertificateValidator shorthand — accepts any certificate the server presents. TLS still encrypts the traffic, but it no longer authenticates the peer, so a network attacker can intercept, read, and modify every request and response. This ships to production unnoticed because nothing fails: requests succeed, tests pass, and the only signal is the missing authentication.

Bad

var handler = new HttpClientHandler
{
    ServerCertificateCustomValidationCallback = (message, certificate, chain, errors) => true
};
handler.ServerCertificateCustomValidationCallback =
    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

Better

Remove the callback entirely so the platform validates the certificate chain:

var handler = new HttpClientHandler();

When a private CA or self-signed certificate is genuinely required (for example an internal test environment), pin the expected certificate or thumbprint instead of accepting everything:

handler.ServerCertificateCustomValidationCallback = (message, certificate, chain, errors) =>
    certificate is not null &&
    string.Equals(certificate.Thumbprint, ExpectedThumbprint, StringComparison.OrdinalIgnoreCase);

Current Detection

The implementation reports assignments and object-initializer entries that set ServerCertificateCustomValidationCallback on HttpClientHandler or WinHttpHandler when the value is a lambda or anonymous method that provably returns the constant true, or the DangerousAcceptAnyServerCertificateValidator property. The property and validator are validated with Roslyn type information when available, with a syntactic fallback for unresolved snippets that visibly declare a handler-typed receiver. Callbacks that inspect the certificate, chain, or errors — even ones that return true conditionally — are skipped, and test-attributed types and methods are skipped.

Suppression

Suppress only for throwaway local diagnostics where TLS authentication is intentionally out of scope. Never suppress in code that ships: prefer certificate pinning or a private-CA check over disabling validation.

References