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 anhttp://
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:
Start the IIS Manager (
InetMgr.exe
)Navigate to
Sites
and click onDefault Web Site
In the
Actions
menu selectHSTS...
Check the
Enable
checkbox, define themax-age
value and select the directives according to the description in this articleImportant
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.
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:
Start the IIS Manager (
InetMgr.exe
)Navigate to
Sites
and click onDefault Web Site
In the
Actions
menu selectHSTS...
Uncheck all directives, set the
max-age
directive to0
and finally uncheck theEnable
checkboxClick
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:
- 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).
- Type
edge://net-internals/#hsts
in the address bar and press Enter. - 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: