Strict-Transport-Security header
HSTS is present with max-age of at least 6 months.
- Severity
- high
- Tier
- Passive: runs on any URL
- Category
- Security
- Fix
- Summary below; full runbook in the Fix Kit, Module 01: Ship it
- Id
- hsts
What this means
Passing means your HTML response carries a Strict-Transport-Security header with a max-age of at least six months. Failing means the header is absent, or its max-age is too short to matter. The header tells a browser to use https for your domain on every later visit without asking.
How we test it
We fetch the home page over https and read the response headers at the final URL. A strict-transport-security line with a max-age of 15768000 seconds or more passes. A header that is present with a shorter max-age warns. No header fails. We only read the header on the https response, so a site that never reaches https fails the redirect check instead of this one.
Why it matters
Stops downgrade attacks after the first visit. Without it, every visit begins with a plain http request that can be intercepted before the redirect arrives; with it, the browser rewrites the address to https before any request leaves the machine. This is one of the six headers the kit describes as set once, completely, in one project and missing from the next three, because they lived in a config file nobody copied. The kit ships them as a template so that cannot happen again.
The fix
Add Strict-Transport-Security: max-age=63072000; includeSubDomains; preload to the headers block that applies to every route: the headers array in vercel.json with "source": "/(.*)" on a static site, or the securityHeaders constant used by headers() in next.config.ts on Next.js, both of which the kit provides as templates. Push, wait once, and confirm with curl -sI https://YOUR_DOMAIN | grep -i '^strict-transport-security'.
The full runbook is in the Fix Kit, Module 01.
Prompt for your AI
Paste this into the coding agent that built the app. It reproduces the finding and stops before changing anything; the fix steps are in the kit.
Do not change anything. This is a verification pass. Run: curl -sI https://YOUR_DOMAIN | grep -i '^strict-transport-security' and show me the output. Run the same against https://YOUR_DOMAIN/ANY_INNER_PAGE and show me the output. Open vercel.json or next.config at the repo root and show me the entry for Strict-Transport-Security, or tell me there is none. If a value is present, tell me the max-age in seconds and whether it is at least 15768000. List what it would take to add the header to every route, and stop there. Run: curl -sI https://YOUR_DOMAIN | grep -ic '^strict-transport-security' and show me the output. Expected on a passing site: 1.
Grade your own URL
Every grade lists this check with its evidence for your site. Two free grades a day.