Is it safe for multiple threads to set ServicePointManager.ServerCertificateValidationCallback?

c#

Solution

If you need to override default certificate validation, consider one or more of the following:

- Set `ServerCertificateValidationCallback` once and only once -- during application start up or possibly in a static constructor. This eliminates the risk of thread contention.

Since you're making security more permissive, limit the behavior to debug builds with conditional compilation:

#if DEBUG
    ServicePointManager.ServerCertificateValidationCallback += Callback;
#endif

Finally, remember that your delegate is a rich function. You don't have to simply return `true`. You can interrogate the request and decide how to handle it.

ServicePointManager.ServerCertificateValidationCallback += Callback;

static bool Callback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (IsInternalRequest(sender))
    {
        return true;
    }
    else
    {
        return IsExternalRequestValid(sender, certificate, chain, sslPolicyErrors);
    }
}

Problem

To ignore the ssl certificate errors, I am setting `ServicePointManager.ServerCertificateValidationCallback` in a static method before making a `HttpWebRequest`. I only want this to be done for internal requests and so I am resetting the property to its default value in the `finally` block. But because it is a web application, will there be an issues when multiple threads are modifying the property? Here is how I am using the property ``` public static String GetResource() { try { ServicePointManager.ServerCertificateValidationCallback += delegate { return true; }; } catch() { } finally { ServicePointManager.ServerCertificateValidationCallback -= delegate { return false; }; } } ``` - Will this code be threadsafe? The documentation on msdn says that any static members of the type ServicePointManager are threadsafe, but I just wanted to confirm. http://msdn.microsoft.com/en-us/library/zkfa48de%28v=vs.80%29.aspx - The code in the finally block, is that the correct way to reset it to the default value?

Original source