In previous posts, I’ve talked about implementing web security features such as HTTPS, CSP, HPKP and HSTS. Almost all of these are things we can configure ourselves within our web applications responses to client requests however one of these features, HSTS requires a little more work to fully implement. HSTS is a technology of two […]
In previous posts, I’ve talked about implementing web security features such as HTTPS, CSP, HPKP and HSTS. Almost all of these are things we can configure ourselves within our web applications responses to client requests however one of these features, HSTS requires a little more work to fully implement.
HSTS is a technology of two halves. HTTP Strict Transport Security (HSTS) is a feature which allows a website to instruct the client that it should never be downgraded to HTTP and should only ever request and receive data from the site over HTTPS. We can easily implement this, in the case of Windows and IIS, using a web.config file outbound rewrite rule which I covered in the previous post, Working Hard on Web Security.
The trouble is, this is only half the battle. If a client repeatedly visits your site, their browser will know as a result of previous visits to always use HTTPS due to having previously seen the HSTS header but what about new visitors? What happens if your site is victim of a downgrade attack between you implementing HTTPS and HSTS and the first time a user visits? Their browser doesn’t know it should be using HSTS already so we have a problem.
HSTS Preloading is the second half of the HSTS technology. The way HSTS Preloading works is by maintaining a list of websites which support HSTS already present in the browser so that when a user tries to visit a site for the first time, it can check against it’s internal list whether HTTPS should be used. Now, with preloading, if the site becomes victim to a HTTP downgrade attack between you implementing HTTPS and HSTS and the first time a user visits, the browser already knows.
HSTS Preload Support
HSTS Preloading is performed by adding a site to a list of known HSTS enabled websites. The site can be found at https://hstspreload.org/. Support for HSTS Preloading is present in most of the modern browsers. The list is actually maintained and updated by Google because Chrome was the first browser to introduce the feature however since then, Google have given access to the list to other vendors and browsers.
Supporting HSTS Preloading in Azure Web Apps
HSTS Preloading has a few requirements. Nothing major or scary but they are all worthy of knowing to allow you to successfully implement it. The focus, as per the title is how to implement this in Microsoft Azure using an Azure Web App platform as a service website, the technology I use to host this site.
For the purposes of this article, I will assume that you already have HTTPS working on the site. If you have read my previous article on configuring aspects of web security, you will understand that we use a URL Rewrite rule to push all HTTP traffic over to HTTPS and then use an outbound URL Rewrite rule to apply the HSTS header. That is sufficient for a standard HTTPS implementation, however for HSTS Preloading, depending on your site, there may be one extra configuration required.
If like me, you publish your site without the www prefix, then we need to configure the site to listen to both the non-www and the www URL and we need a certificate to match both. I buy certificates from Comodo which handily have the non-www and the www prefix URLs as Subject Alternative Names on the single certificate however if your provider does not do this, you will need multiple certificates and to bind them accordingly.
In the Azure Portal, open the Web App and head to Custom Domains. On this blade, ensure that you have both the www.domain.suffix and the domain.suffix host names configured (if you require both).
As you can see from the image above, I have both hostnames already defined so I am good here. If you don’t have both and you are using domain.suffix without the www prefix you will need to have both listed as I already mentioned. If you try to test the site against the HSTS Preload list site at this stage, you will get a warning.
As the error clearly states, this is because I am currently only serving a valid certificate for the richardjgreen.net domain and not for the www.richardjgreen.net domain. Even though my rewrite rules push all the client traffic to richardjgreen.net, it is still possible for a client to hit www.richardjgreen.net initially and HSTS requires that all routes are satisified. Without a binding for my personal certificate on this hostname, the default Azure Website certificate is served which obviously fails name checking.
Back in the Azure Portal, head to the SSL Certificates blade for the Web App.
To confirm what I am talking about, here are the bindings configured on the site currently and as you can see, there is only one. Hit the Add Binding link to start configuring a new binding for the site.
From the Hostname drop down menu, select the www.domain.suffix hostname or whichever you currently are missing a binding for. Select the relevant certificate which matches that name and select either an SNI SSL or an IP SSL binding. I use SNI SSL out of principle because its cheaper and I am not concerned about down-level client support for IP SSL clients.
After adding the new binding, head back to the HSTS Preload list site and re-run the test. This time, you should be greeted with a green box informing you that you meet all the criteria and that you can proceed to adding yourself to the list. Click the Submit button and you are done.
Once you have registered, you will go into a queue. As new Chrome builds are compiled and rolled out, updates to the HSTS Preload list will be included in those builds. Don’t expect to be on the preload list overnight, it is something which will take weeks’ or potentially months to occur. You need to ensure that your site continues to meet all of the HSTS Preload requirements during this time as submissions will be re-tested to verify that you are still eligible.