0

I am facing issue with SSL certificates in IIS (w3wp.exe) processes. Recently we implemented SSL for our applications.

On developer machines we are using the IIS Express Development Certificate that comes as part of IIS installation. This certificates the 'localhost' hostname for SSL usage. In the IIS there are three different apps (with separate app pools) running. All the apps works fine when accessed via browser, everything is safe and sound.

We have some functionality where one of the apps (w3wp processes) requests data from another app/process. In order to have a single source of the data, we made it so that the process sends post request to the service that can provide the data. This is done simply using LongTimeoutWebClient like so:

using (LongTimeoutWebClient webClient = new LongTimeoutWebClient())
{
    webClient.Headers.Add(HttpRequestHeader.ContentType, "application/json");
    serverResponse = webClient.UploadString(serviceUri, "POST", serializer.Serialize(envelope));
}

As for the serviceUri, it is set correctly https://localhost/Service.svc.

However I am getting following exception System.Net.WebException: 'The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.'

This happens only on localhost and my guess is that it is because the certificate is self-signed - issued by localhost for localhost.

I know I can work around this by having custom certificate validation callback

ServicePointManager.ServerCertificateValidationCallback =
  (sender, certificate, chain, errors) =>
  {
      if (errors == SslPolicyErrors.None)
          return true;

      if (sender is HttpWebRequest request)
          return request.RequestUri.Host == "localhost";

      return false;
  };

My question however is: is there a easier/more elegant solution to this problem? Basically what this workaround says is that on localhost I am trusting all requests as long as they target localhost. Which is fundamentally not wrong, it's just that it doesn't feel right.

RhodryCZ
  • 129
  • 1
  • 8
  • for local development, you could just do this as in this [SO answer](https://stackoverflow.com/a/61803096/14973743), why do you think it is not right ? – Anand Sowmithiran Aug 24 '23 at 09:41
  • I'm not saying it's not right, it's just that I am not really feeling comfortable having this in production code. There probably is no way around this, as the code is part of one of our nuget packages and having production and developer specific implementations would be a hassle. – RhodryCZ Aug 24 '23 at 10:27
  • If you read a little bit more on zero trust https://learn.microsoft.com/en-us/security/zero-trust/zero-trust-overview You should see why you feel uncomfortable. In production it makes no sense to use self signed certificates or ignore certificate errors. Please work with your domain administrators (usually who manage internal certificate authorities) to get the proper certificates. – Lex Li Aug 24 '23 at 13:30
  • On production we do not have this issue and everything works as expected - we have certificates issued by our company's certification authority. It is only on developer localhosts where we use the IIS default self-signed certificate. There are policy reasons why we do not go with company issued certificates instead. – RhodryCZ Aug 25 '23 at 07:11

1 Answers1

0

Another solution is to install the self-signed certificate used by the IIS application into the Trusted Root Certification Authorities store on the local computer. This will make your system trust the certificate, and you don't need to implement a custom certificate verification callback.

Export the Certificate:

  • Open the Certificates MMC snap-in. You can do this by pressing Win+R, typing mmc, and adding the Local Computer Account's Certificates snap-in.
  • Navigate to Personal > Certificates.
  • Find your self-signed certificate (it may have been issued to localhost) and right click on it.
  • Choose All Tasks > Export.
  • Follow the export wizard to export the self-signed certificate.

Import the certificate:

  • Navigate to Certificates (Local Computer) > Trusted Root Certification Authorities > Certificates.
  • Right-click in the right pane, select All Tasks, and click Import.
  • Then follow the wizard to import the self-signed certificate.

This method is only suitable for development and test environments. In production, you should use properly signed SSL certificates from recognized certificate authorities to ensure secure communication between applications.

Refer this link: how to add self-signed certificate as trusted certificate.

YurongDai
  • 1,362
  • 1
  • 2
  • 7