Got into a discussion recently about securing websites via HTTPS and the implications of allowing any part of your site to be loaded via HTTP. The most egregious designs usually loads the site using HTTP and simply completes a form POST for sensitive data via HTTPS. Good enough? Not by a long shot!

Two points I want to bring up about this:

  1. Any part of your site that gets to you via HTTP can easily be manipulated by man in the middle attack. Leaving the integrity of anything in the page in doubt including the endpoint of your “secure” POST.
  2. Non-technical end users are realizing (if only at a high level) that the green lock in the address bar means a more secure conversation.

It is disappointing then to see major sites happily present entire pages (or just resources) over HTTP when there are clear advantages to pushing the entire site via HTTPS. The HTTP Strict Transport Security (HSTS) standard is a relatively new mechanism that is designed to facilitate this practice in conjunction with compliant browser, the abstract for HSTS reads as follows:

This specification defines a mechanism enabling web sites to declare themselves accessible only via secure connections and/or for users to be able to direct their user agent(s) to interact with given sites only over secure connections. This overall policy is referred to as HTTP Strict Transport Security (HSTS). The policy is declared by web sites via the Strict-Transport-Security HTTP response header field

Here are some scenarios it helps combat:

User bookmarks or manually types http://example.com and is subject to a man-in-the-middle attacker

  • HSTS automatically redirects HTTP requests to HTTPS for the target domain

Web application that is intended to be purely HTTPS inadvertently contains HTTP links or serves content over HTTP

  • HSTS automatically redirects HTTP requests to HTTPS for the target domain

A man-in-the-middle attacker attempts to intercept traffic from a victim user using an invalid certificate and hopes the user will accept the bad certificate

  • HSTS does not allow a user to override the invalid certificate message

There are a variety of ways to tackle integration of this solution into IIS, here are the ones I have looked at recently.

Configure IIS directly

IIS does have the ability add custom header fields to the HttpResponse:

  1. Open IIS Manager and navigate to the level you want to manage. For information about opening IIS Manager (instructions assume IIS 7).
  2. In Features View, double-click HTTP Response Headers.
  3. On the HTTP Response Headers page, in the Actions pane, click Add.
  4. In the Add Custom HTTP Response Header dialog box, type a name, and a value or set of values separated with commas (,) in the Name (Strict-Transport-Security) and Value (max-age=31536000) boxes as follows:
You could also add these headers via the web.config, something like this:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
</customHeaders>
</httpProtocol>
</system.webServer>

However, a strict adherence of the protocol means that you should not present this custom header over non-secure transport and unfortunately IIS does not support that type of conditional check. This means even if you force a 30x redirect to HTTPS for all HTTP traffic, that first 30x response over HTTP will contain the custom header.

IIS URL Rewrite

IIS 7 and above enables IIS administrators to create powerful customized rules, this one adds the custom header for only HTTPS traffic.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="Add Custom Header for HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>

ASP.NET HttpModule

Alternatively you could solve this by writing a HttpModule that runs within ASP.NET application context.

public class HSTSModule : IHttpModule 
{
public void Dispose()
{
}

public void Init(HttpApplication context)
{
context.PostRequestHandlerExecute += context_PostRequestHandlerExecute;
}

void context_PostRequestHandlerExecute(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;

if (context.Request.IsSecureConnection)
{
context.Response.AppendHeader("Strict-Transport-Security", "max-age=31536000");
}
}
}

If you elect to use a HttpModule you should be aware of which files are processed by ASP.NET, some static files (css, js, htm) are purposefully not sent through the ASP.NET pipeline, this can be configured within your Web.config but you should be aware of the implications of doing so.

Open Source IIS Module

The simplest alternative is to download and deploy the open source HTTP Strict Transport Security IIS Module, If you are comfortable with C++ and writing IIS modules you can find code details over at GitHub.


Related Posts


November 23, 2014 4:43  Comments [0]
Tagged in ASP.NET | IIS
Share on Twitter, Facebook and Google+