SecHead
Website scannenKontakt
Header Guide17 min read

What is HSTS and Why Every Site Needs It

HSTS (HTTP Strict Transport Security) forces browsers to always use HTTPS. Here's what it does, why it matters, and the exact header value to use.

SL
Seven Labs · 13 January 2026
3,345 words

What is HTTP Strict Transport Security (HSTS) and Why Every Site Needs It

When you type a website address into your browser, how do you know your connection is secure from the very first millisecond? Even if a website automatically redirects HTTP traffic to HTTPS, there is a tiny, almost imperceptible window of vulnerability that attackers can exploit. This is exactly where HTTP Strict Transport Security (HSTS) steps in.

In this comprehensive guide, we will dive deep into the Strict-Transport-Security header. We'll explore why standard redirects are no longer sufficient to protect your users, how to configure HSTS correctly across various server environments, and the safest way to deploy it without breaking your website.


Quick Answer: What is HSTS?

HTTP Strict Transport Security (HSTS) is a web security policy mechanism that forces web browsers to interact with a website only over secure HTTPS connections, never via the insecure HTTP protocol.

Delivered via the Strict-Transport-Security HTTP response header, HSTS completely eliminates the risk of SSL Stripping and prevents users from bypassing browser certificate warnings. Once a browser receives the HSTS header from a domain, it automatically upgrades all future attempts to access that domain via HTTP directly to HTTPS internally, before any network traffic is even generated.

The standard, highly recommended HSTS header looks like this:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

People Also Ask (PAA)

  • What is the difference between HTTPS and HSTS? HTTPS encrypts the data transmitted between the browser and the server. HSTS is an enforcement policy that guarantees HTTPS is used, preventing attackers from forcing a downgrade back to unencrypted HTTP.
  • Do I really need HSTS if I already redirect HTTP to HTTPS? Yes. A standard 301 or 302 redirect happens over the network. An attacker intercepting traffic (Man-in-the-Middle) can block the redirect and serve the user a fake, unencrypted version of the site. HSTS makes the browser enforce the redirect internally, making interception impossible.
  • What happens if I set max-age=0? Setting the max-age directive to 0 tells the browser to immediately expire and remove the HSTS policy for that domain. This is primarily used as an emergency "undo" switch if HSTS was enabled by mistake on a site that still relies on HTTP.
  • Can HSTS be bypassed? If configured correctly and preloaded, HSTS cannot be bypassed by the end user or a network attacker. Browsers will strictly prevent users from clicking through SSL certificate warnings for HSTS-enabled domains.

The Problem: Why HTTPS Redirects Are Not Enough

Most web developers believe that installing an SSL/TLS certificate and setting up a 301 redirect from HTTP to HTTPS means their job is done.

Typically, the flow looks like this:

> curl -I http://example.com

HTTP/1.1 301 Moved Permanently
Location: https://example.com
Server: nginx

To the naked eye, this seems perfectly secure. A user types example.com into their browser, the browser defaults to http://example.com, the server responds with a 301 redirect, and the user lands safely on https://example.com.

The Threat: SSL Stripping and Man-in-the-Middle (MitM) Attacks

The vulnerability lies in that very first HTTP request. Because it is sent over an unencrypted channel, a malicious actor positioned between the user and the server (e.g., on a public Wi-Fi network at a coffee shop) can intercept the request.

This attack, famously demonstrated by Moxie Marlinspike in 2009 as SSL Stripping, works like this:

  1. Interception: The user types example.com. The browser sends an unencrypted HTTP request. The attacker intercepts it.
  2. Proxying: The attacker forwards the request to the legitimate server and receives the 301 HTTPS redirect.
  3. Establishing HTTPS: The attacker follows the redirect and establishes a secure HTTPS connection with the legitimate server on behalf of the user.
  4. Stripping the Encryption: The attacker serves the website back to the user over plain HTTP, removing all secure links (https:// becomes http://).

The user sees the website. It functions normally. But the attacker is now acting as a proxy, reading every password, credit card number, and session cookie transmitted. The only clue the user has is the absence of the padlock icon in the browser's address bar-a detail most users completely overlook.


Enter HTTP Strict Transport Security (HSTS)

HSTS eliminates the SSL Stripping vulnerability by changing how the browser behaves.

When your server sends the Strict-Transport-Security header over a valid HTTPS connection, it gives the browser a strict instruction: "For the next X amount of time, do not even attempt to contact me over HTTP. If the user types http://, change it to https:// yourself before sending the request."

How HSTS Closes the Gap

  1. Internal Redirects: The browser performs an internal 307 Internal Redirect from HTTP to HTTPS. No unencrypted request ever leaves the user's device.
  2. Strict Certificate Validation: HSTS fundamentally alters how browsers handle SSL/TLS certificate errors. Normally, if a certificate is expired or self-signed, browsers show a warning but allow the user to click "Advanced -> Proceed anyway". With HSTS enabled, this bypass button is completely removed.
URL: https://example.com
Status: Connection Not Private
Error: NET::ERR_CERT_AUTHORITY_INVALID

Your connection is not private
Attackers might be trying to steal your information from example.com.

example.com normally uses encryption to protect your information. When Google Chrome tried to connect to example.com this time, the website sent back unusual and incorrect credentials.

[Go Back]
(Note: There is no "Proceed to example.com" button available because this domain uses HSTS.)
**CRITICAL SECURITY INTERVENTION:** 
Because the site uses HTTP Strict Transport Security (HSTS), the browser enforces strict validation of the SSL/TLS certificate. The user cannot bypass the warning, completely neutralizing Man-in-the-Middle attacks utilizing fraudulent or self-signed certificates.

Anatomy of the Strict-Transport-Security Header

The HSTS header consists of one required directive and two highly recommended optional directives.

1. max-age=<seconds> (Required)

This dictates how long (in seconds) the browser should cache and enforce the HSTS policy. Every time the user visits the site and receives the header, this timer resets.

  • max-age=300 (5 minutes) - Ideal for initial testing.
  • max-age=86400 (1 day) - Good for early deployment phases.
  • max-age=31536000 (1 year) - The industry standard and a strict requirement for the HSTS Preload list.
  • max-age=0 - Immediately expires the HSTS policy.

2. includeSubDomains (Optional, but critical)

If this directive is present, the HSTS policy applies not only to the apex domain (e.g., example.com) but to all of its subdomains (e.g., blog.example.com, mail.example.com, intranet.example.com).

Warning: Before enabling this, you must ensure that every single active subdomain has a valid SSL/TLS certificate and is configured to support HTTPS. If an old, forgotten subdomain only works over HTTP, includeSubDomains will break access to it completely for any user who has visited your main site.

3. preload (Optional, for ultimate security)

The preload directive indicates that the site owner authorizes browsers to hardcode the domain into their source code as an "HTTPS-only" site. We will cover this extensively in the next section.


The HSTS Preload List: The Ultimate Security

Even with standard HSTS, there is a minor flaw known as the Trust on First Use (TOFU) vulnerability.

If a user has never visited your website before, or if they recently cleared their browser cache, their browser doesn't know about your HSTS policy yet. Their very first request might still go out over HTTP, making them susceptible to a one-time SSL Stripping attack.

To solve this, Google Chrome maintains the HSTS Preload List (which is also adopted by Firefox, Safari, Edge, and others). It is a literal list of domains hardcoded into the browser's source code. If your domain is on this list, the browser will never attempt an HTTP connection to your site, even on the very first visit.

How to get on the HSTS Preload List

To qualify for preloading, your domain must meet all of the following requirements:

  1. Serve a valid SSL/TLS certificate.
  2. Redirect from HTTP to HTTPS on the same host.
  3. Serve all subdomains over HTTPS.
  4. Serve the HSTS header on the base domain for HTTPS requests.
  5. The header must include max-age=31536000 (or greater).
  6. The header must include includeSubDomains.
  7. The header must include the preload directive.

Once these conditions are met, you must manually submit your domain at hstspreload.org.

[!WARNING] Preloading is a one-way street. Removing your domain from the preload list is a painfully slow process. It requires submitting a removal request, waiting for browser vendors to accept the patch, and then waiting months for users to update their browser versions. Only submit your domain if you are 100% committed to HTTPS for the rest of your domain's lifespan.


Implementation Guide: How to Enable HSTS

Implementing HSTS is a matter of adding the HTTP response header to your server's configuration. Crucially, the header must only be served over HTTPS connections. Serving it over HTTP is a violation of the specification and will be ignored by browsers.

Here are the exact configurations for popular web servers and frameworks.

Nginx

To enable HSTS in Nginx, you use the add_header directive. Add this inside your server block that listens on port 443 (HTTPS).

server {
    listen 443 ssl;
    server_name example.com;

    # SSL configuration here...

    # Enable HSTS with 1 year duration, subdomains, and preloading
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    # The 'always' parameter ensures the header is sent for all response codes (e.g., 404s, 500s)
}

Apache

In Apache, you use the Header directive, which requires the mod_headers module to be enabled (a2enmod headers). Add this to your VirtualHost configuration for port 443.

<VirtualHost *:443>
    ServerName example.com
    
    # SSL configuration here...

    # Enable HSTS
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>

Node.js / Express

If your Node.js application handles SSL termination directly (which is rare, but possible), you can set the header via middleware. However, the easiest way to manage security headers in Express is by using the Helmet package.

const express = require('express');
const helmet = require('helmet');
const app = express();

// Use Helmet's HSTS middleware
app.use(
  helmet.hsts({
    maxAge: 31536000, // 1 year in seconds
    includeSubDomains: true,
    preload: true
  })
);

app.get('/', (req, res) => {
  res.send('Secure Hello World!');
});

IIS (Internet Information Services)

For Windows Server environments using IIS, you can add the HSTS header via the web.config file.

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

(Note: Windows Server 2019 and later include native HSTS support built directly into IIS, which is preferred over manual web.config edits.)

Next.js / Vercel

If you are using modern JavaScript frameworks hosted on platforms like Vercel, you can set headers in your configuration files.

Next.js (next.config.js):

module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          {
            key: 'Strict-Transport-Security',
            value: 'max-age=31536000; includeSubDomains; preload'
          }
        ],
      },
    ]
  },
}

Verifying the Implementation: Once deployed, you can verify your configuration using the terminal.

> curl -I https://example.com

HTTP/2 200 
server: nginx
content-type: text/html; charset=utf-8
strict-transport-security: max-age=31536000; includeSubDomains; preload
x-frame-options: DENY

A Safe Deployment Strategy for HSTS

Deploying HSTS with max-age=31536000; includeSubDomains; preload right out of the gate is a recipe for disaster if your infrastructure isn't fully ready. If a single subdomain is still reliant on HTTP, you will completely lock your users out of it.

To safely deploy HSTS, follow this phased rollout strategy:

Phase 1: Audit and Monitor

Before touching any headers, crawl your entire domain and all subdomains. Ensure that every single endpoint successfully loads over HTTPS with a valid certificate. Monitor mixed-content warnings to ensure no HTTP assets (images, scripts) are being loaded on HTTPS pages.

Phase 2: The Toe-Dip (Short Max-Age)

Enable HSTS, but with a very short max-age and without includeSubDomains.

Strict-Transport-Security: max-age=300

This applies the policy for just 5 minutes. If something goes catastrophically wrong, the policy will expire shortly, and users will be able to access the site again.

Phase 3: Ramping Up

Gradually increase the max-age over several weeks while monitoring error logs and user complaints.

  • max-age=86400 (1 Day)
  • max-age=604800 (1 Week)
  • max-age=2592000 (1 Month)

Phase 4: Enabling Subdomains

Once you are confident the apex domain is stable, add the includeSubDomains directive. Keep the max-age at 1 month to ensure subdomains don't break.

Strict-Transport-Security: max-age=2592000; includeSubDomains

Phase 5: Maximum Security and Preloading

Finally, bump the max-age to 1 or 2 years, and append the preload directive. Submit your site to the HSTS Preload list.

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

Troubleshooting and Common Mistakes

Even experienced sysadmins can make errors when deploying HSTS. Here are the most common pitfalls:

  • Serving HSTS over HTTP: Browsers are explicitly programmed to ignore the Strict-Transport-Security header if it is served over an unencrypted HTTP connection. This prevents attackers from injecting malicious HSTS headers to cause denial of service. You must serve it over HTTPS.
  • Multiple HSTS Headers: Serving multiple HSTS headers in a single response can cause browsers to ignore the policy entirely. Ensure your load balancer, CDN, and origin server aren't all trying to inject the header simultaneously.
  • Forgetting includeSubDomains: If your main site is example.com but your login portal is secure.example.com, failing to include subdomains leaves the login portal vulnerable to MitM attacks if accessed directly.
  • The "Development Environment" Trap: If you test HSTS on localhost or a staging domain (staging.example.com) and include includeSubDomains while using a shared base domain, you might inadvertently lock yourself out of local development environments that don't have valid SSL certificates.

[!TIP] How to Remove HSTS: If you accidentally locked out your users, change the header to Strict-Transport-Security: max-age=0. This tells browsers to instantly forget the HSTS policy. Note: This will not work if you have already been hardcoded into the browser's Preload list.


Security Considerations and Limitations

While HSTS is a robust security measure, it is not a silver bullet. Security engineers must be aware of its limitations.

1. Network Time Protocol (NTP) Attacks

Because HSTS relies on the browser's system clock to calculate the max-age expiration, a sophisticated attacker capable of manipulating the target's system clock (via an NTP attack) could theoretically trick the computer into thinking the HSTS policy has expired.

2. Phishing and Typosquatting

HSTS protects example.com. It does absolutely nothing to protect a user who accidentally types exampel.com or clicks a phishing link to example-secure-login.com.

3. IP Address Limitations

The HSTS specification dictates that HSTS policies do not apply to literal IP addresses. If a user navigates to https://192.168.1.50, the browser will not cache an HSTS policy for that IP address.


Frequently Asked Questions (FAQ)

1. Is HSTS required for SEO? While Google considers HTTPS a ranking signal, there is no direct SEO penalty for lacking an HSTS header. However, HSTS improves security and slightly improves load times by eliminating the initial HTTP redirect, which can positively impact user experience metrics.

2. Does HSTS slow down my website? No, HSTS actually speeds up subsequent visits to your website. By enforcing the HTTPS redirect internally at the browser level, you eliminate the network latency of the initial HTTP-to-HTTPS redirect round trip.

3. What happens if my SSL certificate expires while HSTS is active? This is a critical failure state. If your certificate expires, browsers will block users from accessing the site, and because of HSTS, they will not be given the option to bypass the warning. It is imperative to use automated certificate renewal (like Let's Encrypt with Certbot) when using HSTS.

4. How do I check if a website uses HSTS? You can use browser developer tools (Network tab -> click the document -> check Response Headers) or command-line tools like curl -I https://domain.com to look for the Strict-Transport-Security header.

5. Can I use HSTS on an intranet or internal corporate network? Yes, as long as your internal network uses valid, trusted SSL/TLS certificates. If your internal tools rely on self-signed certificates without an internal Root CA installed on employee machines, HSTS will lock employees out of those tools.

6. Why does the browser ignore the HSTS header on HTTP responses? If browsers accepted HSTS over HTTP, an attacker could intercept an HTTP request to an insecure site and inject a fake HSTS header with an absurdly long max-age. Since the site doesn't actually support HTTPS, this would result in a permanent Denial of Service (DoS) for the victim.

7. How long does it take to get on the HSTS Preload list? After submitting to hstspreload.org, it typically takes a few weeks to be included in the source code of Chromium (Chrome/Edge) and Firefox. However, it can take several months for those browser updates to roll out to end-users globally.

8. How do I clear the HSTS cache in Chrome for local development? In Chrome, navigate to chrome://net-internals/#hsts. Under the "Delete domain security policies" section, enter localhost (or your staging domain) and click Delete.

9. Does HSTS protect against DNS spoofing? HSTS mitigates the impact of DNS spoofing. If an attacker spoofs DNS to point your domain to their server, they still must present a valid SSL certificate for your domain to serve traffic. Since HSTS prevents users from bypassing certificate errors, the attack will fail.

10. Should I set HSTS on my CDN or my origin server? It is generally best practice to set the HSTS header at the edge (on the CDN or Load Balancer). This ensures the header is attached to all cached responses and reduces the configuration burden on the origin servers.

11. What is the difference between HSTS and HPKP? HTTP Public Key Pinning (HPKP) was a mechanism to tell browsers which specific cryptographic identities they should accept for a domain. HPKP proved too dangerous and complex (often causing self-inflicted outages) and has been deprecated by all major browsers. HSTS remains the standard for enforcing transport security.

12. Can a VPN replace the need for HSTS? No. While a VPN encrypts traffic between the user and the VPN exit node, the traffic between the exit node and the web server could still be unencrypted HTTP. HSTS ensures end-to-end encryption regardless of the user's network setup.

13. Does HSTS work on mobile browsers? Yes. All modern mobile browsers (Chrome for Android, Safari for iOS, Firefox Mobile) fully support HSTS and utilize the same preload lists as their desktop counterparts.

14. What does the includeSubDomains directive actually do? It applies the HSTS rule to all subdomains recursively. If set on example.com, it covers a.example.com, b.example.com, and even nested.c.example.com.

15. Is it safe to use preload immediately? Absolutely not. You should never use the preload directive until you have run HSTS with a long max-age for several months without any issues. Undoing a preload mistake is incredibly difficult.


Conclusion

HTTP Strict Transport Security is no longer an optional "bonus" feature for highly sensitive financial applications-it is a baseline requirement for any modern website. By deploying the Strict-Transport-Security header, you permanently close the door on SSL Stripping attacks, prevent users from making dangerous choices regarding invalid certificates, and ensure that your encryption is enforced 100% of the time.

Take the time to audit your infrastructure, follow a phased rollout strategy, and ultimately aim for inclusion on the HSTS Preload list. Your users' data security depends on it.

Scan your site → to check if your HSTS header is configured correctly.


Meta Title: What is HTTP Strict Transport Security (HSTS) & How to Enable It Meta Description: Learn what HSTS (HTTP Strict Transport Security) is, how it stops SSL stripping and MitM attacks, and step-by-step instructions for Nginx, Apache, and Node. URL Slug: what-is-hsts Keywords: Strict-Transport-Security, HSTS Preload, SSL/TLS, Man-in-the-Middle Attacks, web security headers


Continue your journey into web security with these related, deep-dive articles from the SecHead team:

Related articles

Free tool

Check your own security headers

Instant grade, plain-language explanations, and a full remediation plan - no signup needed.

Scan your site now →