Skip to content

Proposal: HttpClientHandler.DangerousAcceptAnyServerCertificateValidator property #21672

@stephentoub

Description

@stephentoub

We have what in my mind is a big problem with HttpClient in 2.0: to use HttpClient with self-signed certs (very common in testing environments), you need to hook up a ServerCertificateCustomValidationCallback; that will override the default verification and can be made to always return true. We do this in all of our HTTP testing in corefx, ASP.NET did it in theirs, etc.

Unfortunately, this doesn't work on macOS nor on several Linux distros. The problem is that libcurl only supports the necessary callbacks to enable this when using an OpenSSL backend, and if such a backend isn't in use, we can't enable this delegate callback and thus throw a PlatformNotSupportedException when trying to hook up the delegate.

As it stands today, basically none of our https testing for HttpClient is running on macOS/CentOS/RHEL/Fedora, ASP.NET recently had to switch away from HttpClient for their testing because of this, etc.

Proposal:
We add the following property to HttpClientHandler:
public class HttpClientHandler
{
public bool ValidateServerCertificate { get; set; } = true;
...
}
The default behavior is as things are today. But if you set ValidateServerCertificate to false, we disable verification, both built-in and custom via the callback. We should be able to do that on all Unix's via libcurl's https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html, and we can do so on Windows simply by substituting a delegate { return true; } delegate (or tweak a setting if there is one).

Updated proposal (5/13/2017):
We add the following property to HttpClientHandler:

public class HttpClientHandler
{
    public static Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> DangerousAcceptAllCertificatesValidator { get; } = delegate { return true; };
    ...
}

A developer can use this delegate with

handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAllCertificatesValidator;

For platforms that already support the callback, nothing need change, although they could be optimized to specially recognize this delegate instance to avoid the callback needing to be invoked. For platforms that don't support the callback, we can use object equality to check for this delegate instance: if any other instance is supplied, we continue to throw a PNSE, but if this instance is supplied, we flip the appropriate options so that certificates are not validated and all are accepted.

cc: @bartonjs, @davidsh, @CesarBS, @CIPop

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions