Cyberis 6 July, 2023

Five-Minute Fix: HTTP Strict Transport Security (HSTS) Not Enforced

Description

HTTP Strict Transport Security (HSTS) is a security enhancement for web applications in the form of a response header.  When a secure web application does not return a 'Strict-Transport-Security' header with its responses to requests, this weakness will usually be reported by a vulnerability scanner or in a penetration test report.  HSTS is supported by all major browsers, other than Opera Mini.

HSTS is a mechanism which is used to instruct the web browser that it must use HTTPS to access the website, thus preventing any communication over unencrypted HTTP. When a web browser observes a web application returning a 'Strict-Transport-Security' header, the browser will remember for a length of time (specified by the "max-age=<expire-time>" directive) that the web application is only to be accessed by HTTPS.  The header has an additional directive, to further increase security, 'includeSubDomains', that will force HTTPS on all sub-domains as well. (As cookies can be manipulated from sub-domains, excluding the 'includeSubDomains' directive in the header can allow for a broad range of cookie-based attacks, that HSTS would typically prevent if this were included.)

Once a website is flagged by the web browser as a secure only site via HSTS, attempts to follow unencrypted (HTTP) links to the site will fail, and this can provide an excellent level of protection against inadvertent insecure data transmission, and against attacks which aim to strip encryption from communications with the site for interception purposes.

HSTS is a "trust on first use" protocol, as a browser needs to receive an initial 'Strict-Transport-Security' header from the web application before knowing that the site is to be accessed via secure connections only.  If an adversary is able to intercept a user's first communication with a protected application, therefore, and strip the HSTS header from the response, the control may not be effective.

An additional directive - 'preload' - is available, which can mitigate this potential window of opportunity for an attacker before a first visit. A site owner is able to add their domain to a global list of hosts that enforces the use of HTTPS only. The list of preloaded sites is hardcoded into a web browser, and this lets the browser know that a connection should be secure before any initial connection is made. Whilst this stops attackers from having the opportunity to intercept a connection and redirect the client to an unencrypted HTTP connection, it also requires that an HSTS header includes subdomains and has an expiration timeline of at least a year.  There can be downsides to preloading HSTS from a productivity point of view, therefore - if a subdomain requires insecure access, or certificate problems are encountered, removing a site from a preloaded list may be very time-consuming.  Organisations should therefore consider carefully whether inclusion in a preload list is suitable for their domains.

In order to be effective, a browser needs to observe the 'Strict-Transport-Security' header only once so it's not strictly necessary to add the header to every server response, but it's helpful to ensure that the header is returned from as much of the URL space as possible to ensure it is 'seen' at the earliest opportunity by a user's browser.  

There is some controversy about HSTS potentially allowing site owners to identify users without cookies, leading to privacy concerns.

Risk/ Impact

If a web application is not returning Strict-Transport-Security headers, users are not prevented from connecting over an unencrypted connection. The impact is twofold.  

First, a user may inadvertently access an insecure version of the site over HTTP rather than HTTPS, and could potentially disclose sensitive data in an unencrypted form as a result.  

Second, a suitably-positioned attacker, who can intercept and modify the user's internet traffic, could perform an attack where encrypted HTTPS connections are re-written as unencrypted HTTP connections. As the user's browser will have no instructions that access to the site should be encrypted, as HSTS is not in use, the browser will likely proceed with the unencrypted connection.  This is called SSL stripping, and can be automated by the ‘sslstrip’ tool. Sensitive information sent unencrypted, such as credentials and card data, could then be stolen by the attacker.

Remediation

Before configuring HSTS on a web application, it is important to ensure that a valid X.509 certificate is implemented for the site.  Having ensured that a valid, trusted certificate is configured for the site, the 'Strict-Transport-Security' header needs to be added to response headers for the site.

Instructions to add a Strict-Transport-Security header vary between service providers. This guide will cover how to apply the header to Apache, IIS, and NGINX servers:

 

Apache Web Server:

Ensure that the headers module is added to the global server configuration file (e.g., /etc/apache2/httpd.conf)

LoadModule headers_module modules/mod_headers.so

Configure the header settings per enabled website using TLS - configuration files are usually in /etc/apache2/sites-enabled/

Add the following to each site configuration files, inside the VirtualHost section:

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

 

NGINX:

Add the following to the top-level server block for the secure server within the NGINX configuration files:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

NGINX configuration blocks inherit add_header directives from their enclosing blocks, so if location blocks include other add_header directives, the Strict-Transport-Security header will also need to be redeclared within this block.


IIS Web Server:

Add the header using ‘Custom Headers’ in the web.config file for the site:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <system.webServer>
       <httpProtocol>
           <customHeaders>
               <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
           </customHeaders>
       </httpProtocol>
   </system.webServer>
</configuration>

Systems should be thoroughly tested before deploying the fixes in a live environment.

References:

If you would like to learn more, we recommend the following references.

Improve your security

Our experienced team will identify and address your most critical information security concerns.