HTTP Strict Transport Security (HSTS) is a vital web security policy mechanism that helps to protect websites against man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking. It’s a straightforward yet powerful method, widely supported by modern browsers, ensuring that web browsers interact with a website exclusively through secure HTTPS connections. HSTS effectively eliminates the vulnerabilities associated with insecure HTTP to HTTPS redirects.
When a browser recognizes that a website has implemented HSTS, it enforces two critical behaviors:
- Automatic HTTPS Connections: All communications with the website are conducted over
https://
, regardless of whether anhttp://
link is clicked or the domain is entered without specifying the protocol. - Bypass Insecure Certificate Warnings: Users are prevented from bypassing warnings related to invalid SSL/TLS certificates, reinforcing secure connections.
Websites activate HSTS by sending a special HTTP header in responses over HTTPS connections.
In its most basic implementation, an HSTS policy instructs the browser to enable HSTS for the specific domain and its immediate subdomains, remembering this setting for a defined period, specified in seconds:
Strict-Transport-Security: max-age=31536000;
For a more robust and highly recommended security posture, the HSTS policy can be extended to include all subdomains and signal readiness for browser “preloading”:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
When deploying this enhanced form of HSTS, it’s important to remember:
- The HSTS policy should be configured on the root domain (e.g.,
https://yourdomain.com
), not just onhttps://www.yourdomain.com
. - Every subdomain associated with the primary domain must support HTTPS. Note that individual subdomains are not required to have their own HSTS policies if the root domain policy includes subdomains.
Further details on how to configure HSTS policies on popular web servers are provided below.
The Genesis of HSTS
The concept of Strict Transport Security was first proposed in 2009, largely inspired by security researcher Moxie Marlinspike’s demonstration of SSL stripping techniques. These techniques highlighted how attackers could exploit insecure redirects to downgrade connections and intercept sensitive data. Recognizing the urgency, major web browsers quickly adopted HSTS, and it was officially standardized as RFC 6797 in 2012.
The core issue HSTS addresses is the inherent vulnerability present even when websites switch to HTTPS. Users might still inadvertently connect via HTTP due to various reasons:
- Default Protocol: When a user types a domain like “example.com” into the address bar, browsers typically default to
http://
. - Outdated Links: Users may click on older links that mistakenly use
http://
URLs. - Network Manipulation: Malicious networks can actively rewrite
https://
links tohttp://
to facilitate attacks.
Websites aiming for HTTPS often still listen on port 80 (HTTP) to redirect users to the secure HTTPS version. For example:
$ curl --head http://github.com
HTTP/1.1 301 Moved Permanently
Location: https://github.com/
This redirect itself is a security weak point. It provides an opportunity for attackers to intercept initial communications, potentially capturing session cookies or maliciously redirecting users to phishing sites.
HSTS mitigates this risk by instructing the browser to remember that a site should only be accessed over HTTPS. This is achieved by sending the Strict-Transport-Security
header when a user connects securely. For instance:
$ curl --head https://github.com
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
This action enables HSTS for github.com
. Once HSTS is active, any attempt to access http://github.com
will automatically be converted by the browser to https://github.com
before the request is even sent.
In the example above, the browser will enforce the HSTS policy for one year (31536000 seconds). The policy is renewed each time the browser receives the header, meaning as long as a user visits https://github.com
at least annually, HSTS protection remains indefinite.
HSTS Preloading: Extending Initial Protection
For HSTS to be effective, a user’s browser must first encounter the HSTS header from the website. This implies that users are vulnerable until their initial successful HTTPS connection to a domain.
Furthermore, in many scenarios, a first visit to https://yourdomain.com
might never occur. Consider these common situations:
- Direct to www Subdomain: Many websites, especially larger organizations, redirect directly from
http://yourdomain.com
tohttps://www.yourdomain.com
. - Redirect Domains: Domains used solely for redirection might redirect from
http://yourdomain.com
directly tohttps://destination.com
.
In both these instances, https://yourdomain.com
is never directly accessed, preventing browsers from receiving an HSTS policy with the crucial includeSubDomains
directive that should apply across the entire domain zone.
To overcome this “first visit” problem, the Chrome security team developed the HSTS preload list. This is a built-in list within Chrome (and shared across Firefox, Safari, Opera, and Edge) containing domains that have HSTS enabled by default, even on the very first visit. This list is publicly available and constantly updated.
Preloading Your Domain for Enhanced Security
The Chrome security team provides a public mechanism for website owners to submit their domains to the HSTS preload list. To be eligible for preloading, domains must meet specific criteria:
- HTTPS Everywhere: HTTPS must be enabled on the root domain (e.g.,
https://example.com
) and all subdomains (e.g.,https://www.example.com
). This is particularly crucial for thewww
subdomain if a DNS record exists for it and includes internal subdomains. - Comprehensive HSTS Policy: The HSTS policy must include all subdomains (
includeSubDomains
directive), specify a longmax-age
(at least one year is recommended), and include thepreload
directive to explicitly consent to preloading. - HTTP to HTTPS Redirection: The website must redirect from HTTP to HTTPS, at least on the root domain.
A valid HSTS header suitable for preloading looks like this:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
As the web progressively transitions to HTTPS as the default protocol, and browsers evolve to phase out plain HTTP, the HSTS preload list (and perhaps HSTS itself) may eventually become redundant.
However, until that fully HTTPS future arrives, the HSTS preload list remains a straightforward and highly effective method for enforcing HTTPS across an entire domain right from the start.
HSTS as an Organizational Imperative
Beyond the direct security benefits for website visitors, particularly those on potentially compromised networks, Strict Transport Security serves a valuable organizational role as a forcing function and compliance tool.
When a domain owner adopts the recommended practices of implementing an HSTS policy on their base domain with includeSubDomains
and preload
, they are making a strong statement: “Every facet of our web infrastructure operates over HTTPS, and will continue to do so.” They are essentially granting browsers permission to rigorously enforce this policy going forward.
This commitment becomes clear, auditable, and provides a tangible way for organizations overseeing HTTPS migration to mark domains as “secure” and “complete.”
Looking at a broader perspective, preloading HSTS for entire top-level domains (TLDs) is technically feasible. Google pioneered this by preloading HSTS for .google
. For smaller, centrally managed TLDs like .gov
, this could be a future possibility, further enhancing overall web security.
Configuration Examples for Common Web Servers
Implementing HSTS is generally straightforward across various web server platforms. Here are configuration examples for popular servers:
nginx:
Within your nginx virtual host configuration, use the add_header
directive. This website, https.cio.gov
, uses nginx and employs these HTTPS rules to set the HSTS header:
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload;' always;
Apache:
In your Apache configuration, utilize the Header
directive to always set the HSTS header:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Microsoft IIS (Internet Information Services):
IIS configurations are managed through a central web.config
file instead of .htaccess
files.
For IIS 7.0 and later, the following web.config
example configures HTTP to HTTPS redirection and enables HSTS for HTTPS connections:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Add Strict-Transport-Security when 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; includeSubDomains; preload" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Generally, the goal is to configure your web server to include a custom HTTP header named Strict-Transport-Security
with the value max-age=31536000; includeSubDomains; preload
(or a variation based on your specific needs).
For server-specific instructions beyond these examples, consult your web server’s documentation.
Further Reading
- HTTP Strict Transport Security (HSTS) – MDN Web Docs
- RFC 6797 – HTTP Strict Transport Security (HSTS)
- hstspreload.org – HSTS Preload List Submission Site