Skip to content

Enable certificate pinning for all requests to login.microsoftonline.com #4646

Open
@svrooij

Description

Summary

The current implementation uses the default httpclienthandler, which trusts the root certificates on the machine. If the machine is compromised, critical security information from the app might be shared with a traffic intercepting proxy.

Motivation and goals

  • Authentication libraries should be as secure as possible
  • Pinning the used root certificate is 9 lines of code
  • adding this extra validation will immediately add extra security to everybody

In scope

An opt-in way on the clients EnforceRootCA() might be a good first step, after that it might become default with an opt-out.

Out of scope

...

Risks / unknowns

There are some valid use cases for intercepting traffic in debug situations, those will stop to work.

Examples

var httpClientHandler = new HttpClientHandler();
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
  // Can someone tell me if this is the default?
  bool defaultResult = errors == System.Net.Security.SslPolicyErrors.None;
  if (!defaultResult) {
    return false; //Fail fast, if the default validation fails.
  }

  if (message.RequestUri!.Host == "login.microsoftonline.com")
  {
    // Microsoft uses DigiCert, so we can check the thumbprint of the root certificate.
    bool msResult = chain!.ChainElements.Last().Certificate.Thumbprint == "A8985D3A65E5E5C4B2D7D66D40C6DD2FB19C5436";
    if (!msResult )
    {
        Console.WriteLine("Got cert with name {0} and thumb {1} for login.microsoftonline.com", cert!.Subject, cert.Thumbprint);
        foreach (var element in chain!.ChainElements)
        {
            Console.WriteLine("Element: {0} thumb: {1}", element.Certificate.Subject, element.Certificate.Thumbprint);
        }
    }
    return msResult;
  }

  return true;
};
var httpClient = new HttpClient(httpClientHandler);

Give brief examples of possible developer experiences (e.g., code they would write).

Don't be deeply concerned with how it would be implemented yet. Your examples could even be from other technology stacks.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions