Configure HTTP Strict Transport Security (HSTS) in Exchange Server

Overview

HTTP Strict Transport Security (HSTS) is a widely supported standard that helps protect website visitors by ensuring that their browser always connects using an HTTPS connection. HSTS works by sending a special HTTP response header from the server to the browser called Strict-Transport-Security (STS). This header includes a max-age directive that specifies the length of time (in seconds) so that the browser should remember that the site can be accessed only using HTTPS. Once a browser receives this header, it automatically changes any HTTP requests to access the site to HTTPS requests.

HSTS doesn't just add protection against common attack scenarios, it also helps remove the need for the common (and now insecure) practice of redirecting users from an HTTP URL to an HTTPS URL. HSTS can also be used to address active and passive network attacks. However, HSTS doesn't address malware, phishing, or browser vulnerabilities.

How HSTS works

The browser is instructed to enforce HSTS when it receives the Strict-Transport-Security header over an HTTPS connection; however, there are some requirements that must be met before the browser enforces HSTS. Specifically, the certificate used to encrypt the session:

  • Must be valid and trusted by the client;
  • Must not be expired; and
  • Must contain the domain or subdomain that was called in the browser.

See Securely browse the web with Microsoft Edge for more general recommendations.

Once the browser is aware that a domain has enabled HSTS, it:

  • Always use a https:// connection, including when clicking on an http:// link or after typing a URL into the address bar without specifying a protocol.
  • Removes the ability for users to click through warnings (for example, expired, or invalid certificates, name mismatches, etc.).

There are some scenarios (for example, user has a new computer, new profile, new browser or has cleared browser data and settings) where a user is vulnerable for a short period of time because they're visiting the site for the first time without HSTS being enforced. To address these scenarios, the Chromium project maintains an HSTS Preload List (which is also used by other browsers like Microsoft Edge and Mozilla Firefox). The Preload List enforces HSTS even when visiting a site for the first time.

You can submit your domain to the HSTS list. The webserver (or in our case, your Exchange server) must also send the preload directive as part of the Strict-Transport-Security header to signal that HSTS preloading should be performed by the browser.

How Exchange Server handles HTTP connections

By default, Exchange Server doesn't redirect HTTP to HTTPS traffic, as the Default Web Site requires SSL. See Default settings for Exchange virtual directories for more information.

However, it's possible to configure an automatic redirect from HTTP to HTTPS by following the steps outlined in Configure http to https redirection for Outlook on the web in Exchange Server, and as a result, Exchange Server accepts connections established via HTTP and responds with an HTTP 302 redirect.

HSTS can help to greatly reduce the number of insecure HTTP to HTTPS redirects as the rewrite to HTTPS is performed by the browser itself and no longer by the server as part of an HTTP 302 redirect response. Using HSTS can also lead to performance improvements, although that isn't its primary purpose.

Regardless of the default configuration (which doesn't allow unencrypted connections), it's a good security practice to provide the Strict-Transport-Security header as part of the response header.

Enable HSTS on Exchange Server

The STS header can be configured on Exchange Server 2019 and Exchange Server 2016, although the way you configure each version is different.

Important

HSTS must only be configured on the Default Web Site as this is the endpoint to which clients connect. HSTS must not be configured on the Exchange Back End. You should also consider configuring HSTS via Response Header on devices that are operating in front of an Exchange server over Layer 7 (e.g., load balancers or reverse proxies).

It's good practice to start with a max-age configuration of 300 (seconds) which is 5 minutes. After the change has been made, you should closely monitor client connectivity to the Exchange server and roll back the change if any issue arises.

Update to a max-age value of one week (604800) or one month (2592000) and wait for the full max-age of the stage before you move on. A max-age value of one year (31536000) should be set as a minimum from a security point of view and is also at least required, if you plan to add your domain to the HSTS Preload List. Setting the max-age value to a value of two years (63072000) is recommended.

Note

The following examples set the max-age value to 300 seconds which is a configuration that should be used only for validating functionality. Make sure to adjust the attribute value to a higher value when you are ready to bring the configuration to production.

Exchange Server 2019

To configure Exchange Server 2019 for sending the Strict-Transport-Security header, you can use the Windows PowerShell or the IIS Manager user interface (UI). In the following section, we describe both methods. The HSTS configuration is a per-server configuration and must therefore be done on every Exchange server.

HSTS configuration via PowerShell

Run the following commands from an elevated PowerShell window to configure and enable HSTS:

Note

To configure a higher max-age value for Exchange Server 2019, you can run the commands again by using a higher value. There is no need to remove the existing configuration beforehand.

Import-Module IISAdministration
Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay

$sitesCollection = Get-IISConfigSection -SectionPath "system.applicationHost/sites" | Get-IISConfigCollection
$siteElement = Get-IISConfigCollectionElement -ConfigCollection $sitesCollection -ConfigAttribute @{"name"="Default Web Site"}
$hstsElement = Get-IISConfigElement -ConfigElement $siteElement -ChildElementName "hsts"
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "enabled" -AttributeValue $true
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "max-age" -AttributeValue 300
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "includeSubDomains" -AttributeValue $true

If you plan to add your domain to the HSTS Preload List, you must make sure that the preload directive is also sent as part of the Strict-Transport-Security header. You must not send the preload directive if you have no plans to submit your domain to the HSTS Preload List.

Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "preload" -AttributeValue $true

Finally, the following commands must be run to complete the HSTS configuration:

Stop-IISCommitDelay
Remove-Module IISAdministration

HSTS configuration via IIS Manager

Do the following steps in the Internet Information Services Manager to configure and enable HSTS:

  1. Start the IIS Manager (InetMgr.exe)

  2. Navigate to Sites and click on Default Web Site

  3. In the Actions menu select HSTS...

  4. Check the Enable checkbox, define the max-age value and select the directives according to the description in this article

    Important

    We can't redirect HTTP to HTTPS using the HSTS configuration, as this breaks connectivity for some scenarios, including the Exchange Management Shell (EMS). If you want to enable HTTP to HTTPS redirect, you must follow the steps outlined in Configure http to https redirection for Outlook on the web in Exchange Server.

  5. Click OK to complete and activate the configuration

Exchange Server 2016

Note

While HSTS configuration is possible via UI on operating systems supported by Exchange Server 2019, this control is not natively available on operating systems supported by Exchange Server 2016. We therefore only describe the steps to be done via PowerShell.

To configure Exchange Server 2016 for sending the Strict-Transport-Security header, run the following commands from an elevated PowerShell window. The HSTS configuration is a per-server configuration and must therefore be done on every Exchange server:

Note

To configure a higher max-age value for Exchange Server 2016, you must first remove the HTTP Response header before running the following commands again.

Windows Server 2012 & 2012 R2

If you don't plan to add your domain to the HSTS Preload List, you must make sure that the preload directive isn't sent as part of the Strict-Transport-Security header. Run the following command to configure HSTS without sending the preload directive:

Import-Module WebAdministration
Add-WebConfigurationProperty -Filter "system.webServer/httpProtocol/customHeaders" -PSPath "IIS:\Sites\Default Web Site" -Name . -AtElement @{name="Strict-Transport-Security"} -Value @{name="Strict-Transport-Security";value="max-age=300; includeSubDomains"}

or

If you plan to add your domain to the HSTS Preload List, you must make sure that the preload directive is sent as part of the Strict-Transport-Security header. Run the following command to configure Exchange Server to send the preload directive as part of the HSTS configuration:

Import-Module WebAdministration
Add-WebConfigurationProperty -Filter "system.webServer/httpProtocol/customHeaders" -PSPath "IIS:\Sites\Default Web Site" -Name . -AtElement @{name="Strict-Transport-Security"} -Value @{name="Strict-Transport-Security";value="max-age=300; includeSubDomains; preload"}

Windows Server 2016

Import-Module IISAdministration
Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay

$iisConfig = Get-IISConfigSection -SectionPath "system.webServer/httpProtocol" -CommitPath "Default Web Site" | Get-IISConfigCollection -CollectionName "customHeaders"

If you don't plan to add your domain to the HSTS Preload List, you must make sure that the preload directive isn't sent as part of the Strict-Transport-Security header. Run the following command to configure HSTS without sending the preload directive:

New-IISConfigCollectionElement -ConfigCollection $iisConfig -ConfigAttribute @{"name"="Strict-Transport-Security"; "value"="max-age=300; includeSubDomains";}

or

If you plan to add your domain to the HSTS Preload List, you must make sure that the preload directive is sent as part of the Strict-Transport-Security header. Run the following command to configure Exchange Server to send the preload directive as part of the HSTS configuration:

New-IISConfigCollectionElement -ConfigCollection $iisConfig -ConfigAttribute @{"name"="Strict-Transport-Security"; "value"="max-age=300; includeSubDomains; preload";}

Finally, the following commands must be run to complete the HSTS configuration:

Stop-IISCommitDelay
Remove-Module IISAdministration

Disable HSTS on Exchange Server

If you want to stop Exchange Server from sending the Strict-Transport-Security header, you can roll back the configuration on a per-server base. The steps to disable HSTS are different on Exchange Server 2016 and Exchange Server 2019.

Note

The HSTS specification allows you to send the max-age directive with a value of 0. This configuration can be used to overwrite the browsers cached HSTS policy information. If you plan to remove your Exchange Server HSTS configuration, then it may be useful to first set a max-age value of 0 before removing the Strict-Transport-Security header configuration.

Exchange Server 2019

To make Exchange Server 2019 stop sending the Strict-Transport-Security header, you can use the Windows PowerShell or the IIS Manager user interface (UI). In the following section, we describe both methods.

HSTS configuration via PowerShell

Run the following commands from an elevated PowerShell window to disable HSTS:

Import-Module IISAdministration
Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay

$sitesCollection = Get-IISConfigSection -SectionPath "system.applicationHost/sites" | Get-IISConfigCollection
$siteElement = Get-IISConfigCollectionElement -ConfigCollection $sitesCollection -ConfigAttribute @{"name"="Default Web Site"}
$hstsElement = Get-IISConfigElement -ConfigElement $siteElement -ChildElementName "hsts"
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "enabled" -AttributeValue $false
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "max-age" -AttributeValue 0
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "includeSubDomains" -AttributeValue $false

If the previous HSTS configuration was to send the preload directive, make sure to disable this as well:

Important

Remember to request removal from the HSTS preload list as well. If you forget to remove the domain from the preload list, browsers will continue to try to enforce HSTS.

Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "preload" -AttributeValue $false

Finally, the following commands must be run to complete the HSTS configuration:

Stop-IISCommitDelay
Remove-Module IISAdministration

HSTS configuration via IIS Manager

Do the following steps in the Internet Information Services Manager to disable HSTS:

  1. Start the IIS Manager (InetMgr.exe)

  2. Navigate to Sites and click on Default Web Site

  3. In the Actions menu select HSTS...

  4. Uncheck all directives, set the max-age directive to 0 and finally uncheck the Enable checkbox

  5. Click OK to complete the configuration

Exchange Server 2016

Note

While HSTS configuration is possible via UI on operating systems supported by Exchange Server 2019, this control is not natively available on operating systems supported by Exchange Server 2016. We therefore only describe the steps to be done via PowerShell.

To make Exchange Server 2016 stop sending the Strict-Transport-Security header, run the following commands from an elevated PowerShell window on each of your Exchange servers:

Windows Server 2012 & 2012 R2

Import-Module WebAdministration
Remove-WebConfigurationProperty -PSPath "IIS:\Sites\Default Web Site" -Filter "system.webServer/httpProtocol/customHeaders" -Name . -AtElement @{name="Strict-Transport-Security"}

Windows Server 2016

Import-Module IISAdministration
Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay

$iisConfig = Get-IISConfigSection -SectionPath "system.webServer/httpProtocol" -CommitPath "Default Web Site" | Get-IISConfigCollection -CollectionName "customHeaders"

If the previous HSTS configuration did not send the preload directive, then run the following command:

Remove-IISConfigCollectionElement -ConfigCollection $iisConfig -ConfigAttribute @{"name"="Strict-Transport-Security"; "value"="max-age=300; includeSubDomains";}

or

If the previous HSTS configuration was to send the preload directive, make sure to run this command:

Remove-IISConfigCollectionElement -ConfigCollection $iisConfig -ConfigAttribute @{"name"="Strict-Transport-Security"; "value"="max-age=300; includeSubDomains; preload";}

Finally, the following commands must be run to complete the HSTS configuration:

Stop-IISCommitDelay
Remove-Module IISAdministration

Validate that HSTS is working as expected

The best way to confirm that HSTS protection is working as expected is to use a modern browser that supports HSTS (for example, Microsoft Edge, Firefox, Chrome, Safari, Opera, etc.). The following steps can be followed when using the Microsoft Edge browser. If you are using a different browser, consult the documentation to find out what the steps for checking the HSTS flags are:

  1. Open the browser and establish an HTTPS connection to OWA or ECP. Make sure that the certificate returned by the Exchange server matches the (sub-) domain you've used (for example, e2k16-2.contoso.lab) and is trusted by the client machine (as this is required to activate the browser's HSTS protection for the domain).
  2. Type edge://net-internals/#hsts in the address bar and press Enter.
  3. Enter the domain name that you've used to access OWA or ECP (for example, e2k16-2.contoso.lab) into the Query HSTS/PKP domain box and press Enter.

Example:

If the result is Not found, this means that HSTS isn't used for the domain. The reason could be that the URL wasn't visited before or that the entry with the HSTS policy store has expired (it's valid for the time that was specified in the max-age directive).

If a result is found, the output looks like this:

If HSTS is used and a connection isn't trusted (for example, the URL doesn't match the domain for which the certificate is issued or the certificate is untrusted or expired), the user sees the following warning which can't be bypassed:

Blocking page Microsoft Edge:

Blocking page Mozilla Firefox: