devkult_
tools29converters34
home/headers/strict-transport-security

Strict-Transport-Security

response headersecurity

Tells browsers to use only HTTPS for the site for a set period, blocking downgrade attacks.

Once a browser has seen HSTS over HTTPS, it rewrites every http:// request for that domain to https:// before sending it, for max-age seconds. That closes the window in which an attacker on the network could intercept the first plain-HTTP request. Chrome DevTools shows these local rewrites as '307 Internal Redirect'.

Syntax

Strict-Transport-Security: max-age=<seconds>[; includeSubDomains][; preload]

Defined in RFC 6797 — HTTP Strict Transport Security.

Values

max-age=<seconds>how long the browser remembers to use HTTPS only
includeSubDomainsapply to every subdomain too
preloadconsent to inclusion in browsers' built-in HSTS list

Examples

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

one year, all subdomains — a common production value

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

two years, all subdomains, eligible for preloading

Strict-Transport-Security: max-age=300

five minutes — start small while testing

Good to know

  • Browsers ignore HSTS received over plain HTTP; it must arrive over HTTPS.
  • includeSubDomains covers every subdomain, including internal ones that may not have certificates yet.
  • Preloading (hstspreload.org) is slow to undo: removal takes months to reach users.
  • Ramp max-age up gradually — minutes, then a week, then a year or two.

Further reading: Security headers checklist · Security headers generator

How to set Strict-Transport-Security

Express
res.set("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
Next.js (next.config.js)
module.exports = {
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [{ key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains" }],
      },
    ];
  },
};
nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Apache (.htaccess)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Check it

Fetch only the response headers and filter for Strict-Transport-Security. In the browser, it's under Response Headers in DevTools → Network.

curl -sI https://example.com/ | grep -i '^strict-transport-security:'

To compare response headers across many URLs at once, use the HTTP Status Checker.

Frequently asked questions

What does '307 Internal Redirect' mean in Chrome?

HSTS at work: Chrome rewrote http:// to https:// locally because the site sent Strict-Transport-Security earlier or is preloaded. No request reached the server.

How do I turn HSTS off?

Send Strict-Transport-Security: max-age=0 over HTTPS; browsers that see it forget the policy. Preloaded domains must also be removed from the preload list.

Status codes it appears with
Related headers