Jump to content

HTTP Strict Transport Security

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by 199.188.193.145 (talk) at 08:33, 24 March 2012 (Fix bug is HSTS max-age value). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

HTTP Strict Transport Security (HSTS) is a web security policy mechanism whereby a web server declares that complying user agents (such as a web browser) are to interact with it using secure connections only (such as HTTPS).

The policy is communicated by the server to the user agent via a HTTP response header field named "Strict-Transport-Security". The policy specifies a period of time during which the user agent shall access the server in only secure fashion.[1]

Specification history

The HSTS specification is presently an IETF Internet-Draft.[1] The authors originally submitted it as an Internet-Draft on 17 June 2010,[2] and it has undergone at least three revisions since then, and become a "working group item" of the IETF WebSec working group.[3] It was with the conversion to an Internet-Draft that the specification name was altered to "HTTP Strict Transport Security" from "Strict Transport Security". The reason for this name change was given as being due to the specification being specific to HTTP.[4] (Note: the HTTP response header field defined in the HSTS specification remains named "Strict-Transport-Security").

The latest community version of the then-named STS specification was published on 18 December 2009, with revisions based on community feedback.[5]

The original draft specification by Jeff Hodges[6] from PayPal, Collin Jackson[7] and Adam Barth[8] was published on 18 September 2009.[9]

The specification is based on original work by Jackson and Barth as described in their paper “ForceHTTPS: Protecting High-Security Web Sites from Network Attacks”.[10]

Overview

When the HSTS policy is active for a website, a complying user agent does the following:

  1. Automatically turn any insecure links to the website into secure links. (For instance, http://example.com/some/page/ will be modified to https://example.com/some/page/ before accessing the server.)
  2. If the security of the connection cannot be ensured (e.g. the server's TLS certificate is self-signed), show an error message and do not allow the user to access the site.

The HSTS policy helps protect website users against some passive (eavesdropping) and active network attacks. A man-in-the-middle attacker has a greatly reduced ability to intercept requests and responses between a user and a website, while the user's browser has HSTS active for that site.

Applicability

The most important security vulnerability that HSTS can fix is SSL-stripping man-in-the-middle attacks, first introduced by Moxie Marlinspike in his 2009 BlackHat Federal talk "New Tricks For Defeating SSL In Practice."[11] The SSL stripping attack works by transparently converting a secure HTTPS connection into a plain HTTP connection. The user can see that the connection is insecure, but crucially there is no way of knowing whether the connection should be secure. Many websites do not use SSL, therefore there is no way of knowing (without prior knowledge) whether the use of plain HTTP is due to an attack, or simply because the website hasn't implemented SSL. Additionally, no warnings are presented to the user during the downgrade process, making the attack fairly subtle to all but the most vigilent. Marlinspike's sslstrip tool fully automates the attack.

HSTS fixes this problem by informing the browser that connections to the site should always use SSL. Of course, the HSTS header can be stripped by the attacker if this is the user's first visit. Chrome attempts to limit this problem by including a hard-coded list of HSTS sites.[12] Unfortunately this solution cannot scale to include all websites on the internet; a more workable solution can be achieved by including HSTS data inside DNS records, and accessing them securely via DNSSEC.

HSTS can also help to prevent having one's cookie-based website login credentials stolen by widely-available tools such as Firesheep.[13]

Limitations

The initial request remains unprotected from active attacks if it uses an insecure protocol such as plain HTTP or if the URI for the initial request was obtained over an insecure channel. The same applies to the first request after the activity period specified in the advertised HSTS policy expires (sites should set a period of several days or months depending on user activity and behavior). Google Chrome addresses this limitation by implementing a "STS preloaded list".[14]

Support

Websites:

  • PayPal sets the Strict-Transport-Security header on their https-only website.[15]
  • DEF CON website[16]
  • https://(chrome|checkout|health|docs|spreadsheets|sites|appengine|encrypted).google.com/[17]
  • https://market.android.com/[17]
  • https://lastpass.com/[17]
  • https://crypto.is/

Naturally, this is not a complete list of websites which support HSTS.

Browsers:

Implementation

Strict-Transport-Security headers must be sent via HTTPS responses only. Client implementations must not respect STS headers sent over non-HTTPS responses, or over HTTPS responses which are not using properly configured, trusted certificates. The following server configuration snippets should be within the context of an SSL site configuration block, and the code examples are intended to be within the context of HTTPS responses only.

Note that the max-age is provided in seconds. The 500 seconds (8.3 min) in the examples below can be changed to a much larger value depending on how long the web server operator is willing to commit to using HTTPS only. It is recommended to set the max-age to a big value like 31536000 (12 months).

Implementation in Apache.

# load module (example using [RHEL])
LoadModule headers_module modules/mod_headers.so

# Use HTTP Strict Transport Security to force client to use secure connections only
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

# redirect all HTTP to HTTPS
<VirtualHost *:80>
       ServerAlias *
       RewriteEngine On
       RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [redirect=301]
</VirtualHost>

Implementation in lighttpd.

server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
    setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=31536000")
}

Implementation in nginx.

# Use HTTP Strict Transport Security to force client to use secure connections only
add_header Strict-Transport-Security max-age=31536000;

Implementation in PHP.

// Use HTTP Strict Transport Security to force client to use secure connections only
$use_sts = true;

// iis sets HTTPS to 'off' for non-SSL requests
if ($use_sts && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
    header('Strict-Transport-Security: max-age=31536000');
} elseif ($use_sts) {
    header('Location: https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'], true, 301);
    // we are in cleartext at the moment, prevent further execution and output
    die();
}

Implementation in Perl CGI.

# Use HTTP Strict Transport Security to force client to use secure connections only
use CGI;
use URI;

my $q   = new CGI;
my $url = URI->new($cgi->request_uri)
my $use_sts = 1;

if ($use_sts and $url->scheme eq 'https') {
    print $q->header('Strict-Transport-Security' => 'max-age=31536000'); 
} elsif ($use_sts) {
    $url->scheme('https');
    print $q->redirect(status => 301, location => $url);
}

Implementation in Ruby on Rails.

class ApplicationController < ActionController::Base
  before_filter :ensure_proper_protocol

private
  def ensure_proper_protocol
    if request.ssl?
      response.headers['Strict-Transport-Security'] = 'max-age=31536000'
    else
      redirect_to "https://" + request.host + request.request_uri, :status => 301
    end
  end
end

Implementation in ASP.

'Use HTTP Strict Transport Security to force client to use secure connections only
dim use_sts
use_sts = TRUE

if use_sts = TRUE and Request.ServerVariables("HTTPS") = "on" then
    Response.AddHeader "Strict-Transport-Security","max-age=31536000"
elseif use_sts = TRUE and Request.ServerVariables("HTTPS") = "off" then
    Response.Status="301 Moved Permanently"
    if Request.QueryString = "" then
        Response.AddHeader "Location", "https://" & Request.ServerVariables("SERVER_NAME") & Request.ServerVariables("URL")
    else
        Response.AddHeader "Location", "https://" & Request.ServerVariables("SERVER_NAME") & Request.ServerVariables("URL") & "?" & Request.QueryString
    end if
end if

Implementation in C# / ASP.NET.

// Use HTTP Strict Transport Security to force client to use secure connections only
var use_sts = true;

if (use_sts == true && Request.Url.Scheme == "https")
{
    Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
}
else if (use_sts == true && Request.Url.Scheme == "http")
{
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", "https://" + Request.Url.Host + Request.Url.PathAndQuery);
}

Implementation in C# / ASP.NET. Code in the global.asax file:

// Use HTTP Strict Transport Security to force client to use secure connections only
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;
    }
}

Implementation in ColdFusion Markup Language (CFML).

<!--- Use HTTP Strict Transport Security to force client to use secure connections only --->
<cfset use_sts = true>

<cfif use_sts is "True"> 
  <cfheader name="Strict-Transport-Security" value="max-age=31536000">
<cfelseif use_sts is "True"> 
  <cfheader statuscode="301" statustext="Moved permanently">
  <cfheader name="Location" value="https://" + CGI.SERVER_NAME + CGI.SCRIPT_NAME + CGI.QUERY_STRING>
</cfif>

Implementation in JavaServer Pages (JSP) or Java Servlets.

// Use HTTP Strict Transport Security to force client to use secure connections only
boolean use_sts = true;

if(use_sts) {
    if(request.getScheme().equals("https")) {
        // Send HSTS header
        response.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubdomains");
    } else {
        // Redirect to HTTPS
        response.setStatus(301);
        String url = "https://" + request.getServerName();
        if(request.getPathInfo() != null) {
            url = url + "/" + request.getPathInfo();
        }
        if(request.getQueryString() != null && request.getQueryString().length() > 0) {
            url = url + "?" + request.getQueryString();
        }
        response.setHeader("Location", url);
    }
}

Implementation in Visual Basic .NET.

'Use HTTP Strict Transport Security to force client to use secure connections only
Dim use_sts As Boolean = True

If use_sts = True Then
    Response.AppendHeader("Strict-Transport-Security", "max-age=31536000")
ElseIf use_sts = True Then
    Response.AppendHeader("Status-Code", "301")
    Response.AppendHeader("Location", "https://")
End If

Implementation as Struts 2 interceptor in Java.

// Use HTTP Strict Transport Security to force client to use secure connections only
public class StrictTransportSecurityInterceptor extends AbstractInterceptor {
    private static final Log logger = LogFactory.getLog(StrictTransportSecurityInterceptor.class);
    private static final String HSTS_HEADER = "Strict-Transport-Security";
    private static final String HSTS_VALUE_NAME = "max-age=";
    private static final int HSTS_VALUE_IN_SECONDS = 10;
    private static final String HSTS_VALUE_INCLUDE_SUBDOMAINS = "; includeSubDomains";

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        ActionContext context = invocation.getInvocationContext();
        HttpServletResponse response = (HttpServletResponse) context.get(StrutsStatics.HTTP_RESPONSE);
        String headerValue = HSTS_VALUE_NAME + HSTS_VALUE_IN_SECONDS;
        response.addHeader(HSTS_HEADER, headerValue);
        logger.debug("HSTS interceptor with policy: " + headerValue);
        return invocation.invoke();
    }
}

<interceptors>
  <interceptor name="strictTransportSecurityInterceptor" class="yourPackage.StrictTransportSecurityInterceptor"/>
</interceptors>

<action name="yourActionName" class="yourPackage.YourAction">
  <interceptor-ref name="strictTransportSecurityInterceptor"></interceptor-ref>
  <result name="success">/success.jsp</result>
</action>

References

  1. ^ a b "HTTP Strict Transport Security". latest revision. Retrieved 31 Oct 2011. {{cite web}}: Check date values in: |date= (help)
  2. ^ "HTTP Strict Transport Security -00". 17 June 2010. Retrieved 22 July 2010.
  3. ^ "IETF WebSec Working Group". 3 Feb 2011. Retrieved 8 Mar 2011.
  4. ^ Jeff Hodges (30 June 2010). "Re: [HASMAT] "STS" moniker (was: IETF BoF @IETF-78 Maastricht: HASMAT...)". Retrieved 22 July 2010.
  5. ^ "Strict Transport Security -06". 18 December 2009. Retrieved 23 December 2009.
  6. ^ "Jeff Hodges's homepage". on-going. Retrieved 26 Aug 2011. {{cite web}}: Check date values in: |date= (help)
  7. ^ "Collin Jackson's homepage". on-going. Retrieved 8 Mar 2011. {{cite web}}: Check date values in: |date= (help)
  8. ^ "Adam Barth's homepage". on-going. Retrieved 8 Mar 2011. {{cite web}}: Check date values in: |date= (help)
  9. ^ "Strict Transport Security -05". 18 September 2009. Retrieved 19 November 2009.
  10. ^ "ForceHTTPS: Protecting High-Security Web Site from Network Attacks". April 2008. Retrieved 19 November 2009.
  11. ^ https://blackhat.com/presentations/bh-dc-09/Marlinspike/BlackHat-DC-09-Marlinspike-Defeating-SSL.pdf
  12. ^ "Strict Transport Security". Retrieved 22 March 2011.
  13. ^ Jeff Hodges (31 October 2010). "Firesheep and HSTS (HTTP Strict Transport Security)". Retrieved 8 Mar 2011.
  14. ^ Adam Langley (8 July 2010). "Strict Transport Security". Retrieved 22 July 2010.
  15. ^ "Screenshot of Paypal's HTTP request 'Strict-Transport-Security' header"
  16. ^ a b Ristic, Ivan (29 July 2010). Internet SSL Survey 2010 v1.6 (PDF). Black Hat USA. p. 42. Retrieved 19 August 2010. {{cite conference}}: External link in |conferenceurl= (help); Unknown parameter |conferenceurl= ignored (|conference-url= suggested) (help)
  17. ^ a b c d The Chromium Developers (17 November 2010). "Strict Transport Security - The Chromium Projects". Retrieved 17 November 2010.
  18. ^ Jeff Hodges (18 September 2009). "fyi: Strict Transport Security specification". Retrieved 19 November 2009.
  19. ^ "Firefox 4 Features". Mozilla. Retrieved 17 March 2011.
  20. ^ Giorgio Maone (23 September 2009). "Strict Transport Security in NoScript". Retrieved 19 November 2009.
  21. ^ Electronic Frontier Foundation (18 June 2010). "HTTPS Everywhere". Retrieved 18 June 2010.