CA5359: Do not disable certificate validation

Property Value
Rule ID CA5359
Title Do not disable certificate validation
Category Security
Fix is breaking or non-breaking Non-breaking
Enabled by default in .NET 8 No

Cause

The callback assigned to ServicePointManager.ServerCertificateValidationCallback always returns true.

Rule description

A certificate can help authenticate the identity of the server. Clients should validate the server certificate to ensure requests are sent to the intended server. If the ServicePointManager.ServerCertificateValidationCallback always returns true, then by default any certificate will pass validation for all outgoing HTTPS requests.

How to fix violations

  • Considering overriding certificate validation logic on the specific outgoing HTTPS requests that require custom certificate validation, instead of overriding the global ServicePointManager.ServerCertificateValidationCallback.
  • Apply custom validation logic to only specific hostnames and certificates, and otherwise check that the SslPolicyErrors enum value is None.

When to suppress warnings

If multiple delegates are attached to ServerCertificateValidationCallback, only the value from the last delegate is respected, so it's safe to suppress warnings from other delegates. However, you may want to remove the unused delegates entirely.

Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.

#pragma warning disable CA5359
// The code that's violating the rule is on this line.
#pragma warning restore CA5359

To disable the rule for a file, folder, or project, set its severity to none in the configuration file.

[*.{cs,vb}]
dotnet_diagnostic.CA5359.severity = none

For more information, see How to suppress code analysis warnings.

Pseudo-code examples

Violation

using System.Net;

class ExampleClass
{
    public void ExampleMethod()
    {
        ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, error) => { return true; };
    }
}

Solution

using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

class ExampleClass
{
    public void ExampleMethod()
    {
        ServicePointManager.ServerCertificateValidationCallback += SelfSignedForLocalhost;
    }

    private static bool SelfSignedForLocalhost(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
        {
            return true;
        }

        // For HTTPS requests to this specific host, we expect this specific certificate.
        // In practice, you'd want this to be configurable and allow for multiple certificates per host, to enable
        // seamless certificate rotations.
        return sender is HttpWebRequest httpWebRequest
                && httpWebRequest.RequestUri.Host == "localhost"
                && certificate is X509Certificate2 x509Certificate2
                && x509Certificate2.Thumbprint == "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                && sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors;
    }
}