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 9 | 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;
}
}