What is the best way to turn on HTTP Strict Transport Security on an IIS 7 web server?
Can I just through the GUI and add the proper HTTP response header or should I be using appcmd and if so what switches?
What is the best way to turn on HTTP Strict Transport Security on an IIS 7 web server?
Can I just through the GUI and add the proper HTTP response header or should I be using appcmd and if so what switches?
This allows us to handle both the HTTP redirect and add the Strict-Transport-Security header to HTTPS responses with a single IIS site (URL Rewrite module has to be installed):
To supplement voretaq7's answer, you could also do this using the Web.config file (N.B.: To be used for SSL sites only, since it will add the header for both HTTP and HTTPS responses, which is against the RFC 6797 specification, please see the explanation below) — add a block as follows:
Obviously, you may already have a
system.webServer
block in your Web.config, so add this to that, if so. We prefer handling things in the Web.config rather than the GUI, because it means the config changes can be committed to our Git repository.If you wanted to handle the HTTP-to-SSL redirection, as Greg Askew mentioned, you might find it easier to do that with a separate website in IIS. This is how we handle requiring SSL for some client sites. That site contains only an HTTP redirect and some information-disclosure fixes, all in the Web.config:
This is our preferred solution for a couple of reasons — we can easily log redirected traffic separately (as it's in a different IIS log), it doesn't involve more code in the Global.asax.cs (we don't have any code in there, which is a little more convenient for an Umbraco site) and, importantly, it means that all the config is still held in our GIT repo.
Edited to add: To be clear, in order to comply with RFC 6797, the
Strict-Transport-Security
custom header MUST NOT be added to requests made by unencrypted HTTP. To be RFC6797-compliant, you MUST have two sites in IIS, as I've described after the first code block. As Chris points out, RFC 6797 includes:so sending the
Strict-Transport-Security
customer header in response to a non-SSL request would not comply with the specification.IIS has the ability to add custom headers to responses. This would seem to be the easiest way to go about it.
According to the documentation on IIS.net you can add these headers through IIS Manager:
I would use the example from the Wikipedia link you referenced and perform the activity in global.asax for the site. This enables redirecting the request to an https url, and then insert the header into the response.
This is due to the HSTS header must be ignored if it isn't in an https response.
This seems to be a pretty fail safe way of doing this. Add this code in the Global.asax - the Application_BeginRequest event fires first in the Asp.net request lifecycle: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs.110).aspx
Per the spec, http requests must not respond with the header - so this code only adds it for https requests. Max-age is in number of seconds, and it's usually a good idea to put a large value in here (IE - 31536000 indicates the site will run SSL only for the next 365 days)
Using the example provided by Doug Wilson I have created the following two PowerShell functions to add url rewrite rules for redirection to HTTPS and for adding HSTS headers.
These have been tested on Windows 2012 and Windows 2012 R2.
All you need to do is supply the website name. You can optionally give the rules a different name if you do not like the defaults.
One things to note is that from my testing, the Server Variables need to be added to the allow list before being in the response headers. The functions do this for you.
EDIT: See reference on Url Rewrite for HTTP Headers here: http://www.iis.net/learn/extensions/url-rewrite-module/setting-http-request-headers-and-iis-server-variables
According to the makers of HTTP Strict Transport Security IIS Module, just adding the custom header is not compliant with the draft specification (RFC 6797).
You would actually need to install this IIS Module to turn on HSTS on IIS 7.
Update 26 okt 2014: Thanks to the commenter below, I read the module page again and specifically the part that justifies the use of the module over adding custom headers.
An HSTS Host MUST NOT include the STS header field in HTTP responses conveyed over non-secure transport.
If you make sure to add the headers only in HTTPS and NOT in HTTP, you don't need this module and you can use the answer by Doug Wilson. Don't use Owen Blacker's answer cause it doesn't have the https condition.
This can be done by adding following block in Web.Config:
We have to configure on IIS that has the ability to custom headers to response:
Just to add, I see in the comments 2 people talking about 500 errors when you do this. I had this.
If you get a 500 error in IIS it may be because you have added the rule both at the top level, set to inherited, and at the site level.
e.g.
IIS/The Browser doesn't seem to give you any information that you have done this, regardless of your error handling settings