← All checks
SecurityTypical severity: Low

Weak HSTS Scanner

Detects an HSTS header with a low max-age or missing includeSubDomains that leaves downgrade gaps.

What it checks

This scanner reviews your HSTS header and detects when it has a max-age that is too low or is missing the includeSubDomains attribute. That lets it identify HSTS setups that leave exploitable gaps.

Why it matters

HSTS forces browsers to always use HTTPS with your site, but if its duration is very short or it does not cover subdomains, there are windows where an attacker can force an unencrypted connection. That gap enables downgrade attacks that intercept traffic.

How to fix it

Set the HSTS header with a long max-age (typically one year, i.e. 31536000 seconds) and add includeSubDomains to cover the whole domain. This is usually done in your server or CDN configuration, and it is wise to test with a smaller value first if you are unsure.

How this check works

This check only acts if your site already sends the Strict-Transport-Security header; if it is missing altogether, the headers scanner flags it. Scanaris reads the value and checks two things: that max-age is at least one year (31536000 seconds) and that it includes includeSubDomains. If either fails, it opens a low-severity finding with the detail. It is low because a short or partial HSTS still protects something; but it leaves gaps an attacker can use.

What HSTS does and why both attributes

When the browser receives this header over HTTPS, it notes your domain in an internal list and, for as long as max-age says, turns any attempt to go over http:// into https:// before sending anything. That removes the first unencrypted request a redirect cannot avoid. A max-age of a few hours or days leaves the user unprotected every time it expires; hence the one-year minimum. Without includeSubDomains, an attacker can target anything.yourdomain.com over HTTP and, because of how domain cookies work, steal or set cookies that are valid for the main site.

How to fix it

The recommended value:

Strict-Transport-Security: max-age=31536000; includeSubDomains
  • Vercel: sets it by default on custom domains; if you use vercel.json or next.config for other headers, add it there with that value.
  • Netlify: in the _headers file, under /*.
  • Nuxt: in routeRules of nuxt.config, rule '/**'.
  • nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; inside the 443 server block.
  • Express: helmet.hsts({ maxAge: 31536000, includeSubDomains: true }).

Before adding includeSubDomains, confirm that all your subdomains serve HTTPS: the admin panel, the API, the blog on another provider, the mail subdomain if it has a website. Any that only answers over HTTP will stop working in browsers that have already seen the header, and there is no way to undo it until the max-age expires. If you are unsure, start with max-age=86400 and without subdomains, review, and raise the value when everything works.

Preload

With preload and a max-age of at least one year you can ask for your domain to be included in the list Chrome, Firefox and Safari ship with: that way not even the first visit goes over HTTP. It is the usual difference between an A and an A+ in analysis tools. But it is an almost irreversible commitment (leaving the list takes months), so do it only when the whole domain has been on HTTPS for a while without incidents.

Check it is fixed

curl -sI https://yourdomain.com | grep -i strict-transport

It must show a max-age of 31536000 or more and includeSubDomains. Check on the public URL: if you have a CDN in front, that is what has to send it.

Frequently asked questions

Does HSTS replace the HTTP to HTTPS redirect?

No. The header only arrives over HTTPS, so the first visit still needs the redirect. They are complementary: the redirect for the first time, HSTS for all the others.

I have an internal subdomain that only works over HTTP.

Then do not set includeSubDomains until you migrate it, and accept the low-severity finding meanwhile. An unencrypted subdomain is a real risk for the domain's cookies, so the migration is worth it.

What happens if I configure it wrong?

Browsers that received the header will remember the policy until it expires. You can send max-age=0 to ask them to forget it, but only the ones that visit you again over HTTPS will see it. That is why starting with short values is wise.

Check it on your site

Scan your site free and see if this and 44 other checks pass, with a fix prompt for every issue.

Scan my site free

From the blog

Related checks