Tell me more ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question
A lot of this depends on how you're generating the stuff IIS is serving (for example. you can set the header in PHP or ASP.NET pages from within your application). Can you tell us more about your use case? – voretaq7 Aug 13 '12 at 21:33

3 Answers

up vote 5 down vote accepted

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:

  • In the Connections pane, go to the site, application, or directory for which you want to set a custom HTTP header.
  • In the Home pane, double-click HTTP Response Headers.
  • In the HTTP Response Headers pane, click Add... in the Actions pane.
  • In the Add Custom HTTP Response Header dialog box, set the name and value for your custom header, and then click OK.
share|improve this answer
2  
It's also possible to do this in the Web.config, which you might prefer. I've posted the details as a new answer, as they'd be really difficult to read without the sourcecode formatting that's not available in comments. – Owen Blacker Mar 20 at 15:07

To supplement voretaq7's answer, you could also do this using the Web.config file — add a block as follows:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Strict-Transport-Security" value="max-age=31536000"/>
        </customHeaders>
    </httpProtocol>
</system.webServer>

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:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <httpRuntime requestValidationMode="2.0" enableVersionHeader="false" />
  </system.web>
  <system.webServer>
    <httpRedirect enabled="true" destination="https://www.domain.co.uk/"
      httpResponseStatus="Permanent" />
    <httpProtocol>
      <customHeaders>
        <remove name="X-Powered-By" />
      </customHeaders>
    </httpProtocol>
    <rewrite>
      <outboundRules>
        <rule name="Remove RESPONSE_Server">
          <match serverVariable="RESPONSE_Server" pattern=".+" />
          <action type="Rewrite" value="" />
        </rule>
      </outboundRules>
    </rewrite>
  </system.webServer>
</configuration>

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.

share|improve this answer

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.

protected void Application_BeginRequest()
{
    switch (Request.Url.Scheme)
    {
        case "https":
            Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
            break;
        case "http":
            var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
            Response.Status = "301 Moved Permanently";
            Response.AddHeader("Location", path);
            break;
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.