Security Headers and SEO: HSTS, CSP, nosniff and How to Check Them
SEOAudit7 min read
Security headers are HTTP response headers that tell the browser how to treat your site: use HTTPS only, load scripts from approved sources, do not guess file types. They are not a ranking factor, and no source claims otherwise. They still touch search presence, though in an indirect way.
This article separates the real connections from the invented ones. For each header you get a sample value, a way to set it on the server and a way to check the result. The security side of that check is covered by the website security check, and the SEO side by the technical SEO checklist.
How security headers relate to search
Start with the caveat: adding security headers does not lift pages in results by itself. Do not promise that to yourself or to a client.
The real links are these:
- HTTPS. Google's documentation recommends serving pages over HTTPS. The HSTS header helps keep a visitor on HTTPS after the first visit.
- Page rendering. A wrong CSP can block scripts, styles or embeds that a page needs. The page then looks different from what you expect, including for tools that render it.
- File types. The nosniff header makes the browser respect the declared MIME type. A script or stylesheet served with the wrong type is blocked.
- Indexing rules.
X-Robots-Tagis itself an SEO header: it carries indexing instructions in HTTP. - A hacked site. Injected spam, redirects to unknown addresses or malware warnings damage a site's search presence. Security hygiene (CSP, cookie flags, updates) lowers that risk without removing it.
So the honest framing is this: security headers do not speed up growth, they remove risks that can stop it. For the neighbouring technical topics see the guides to robots.txt and the canonical tag.
HSTS: keeping visitors on HTTPS
The Strict-Transport-Security header (HSTS, defined in RFC 6797) tells the browser to open the site over HTTPS only, for a stated time. A typical value:
Strict-Transport-Security: max-age=31536000; includeSubDomainsThe max-age number is in seconds, here one year. A few practical rules:
- Browsers honour HSTS only on responses received over HTTPS. Over plain HTTP the header is ignored.
- After the first visit the browser upgrades to HTTPS on its own, with no HTTP request and no redirect. For returning visitors that saves a round trip to the server.
- Start with a short
max-age, for examplemax-age=300. If nothing breaks after a few days, raise it. includeSubDomainsextends the rule to every subdomain. Make sure each one really works over HTTPS first.- The
preloadtoken, together withincludeSubDomainsand amax-ageof at least one year, lets you submit the domain to the list at hstspreload.org. Getting removed is hard, so do it last.
The header is described in the MDN documentation. HSTS does not replace the HTTP-to-HTTPS redirect: the very first visit without it stays unprotected.
Content-Security-Policy: what the page may load
The Content-Security-Policy header (CSP) lists where a page may take scripts, styles, images and frames from. It is the main defence against injected foreign code. A basic example policy:
Content-Security-Policy: default-src 'self'; img-src 'self' data:; script-src 'self'; frame-ancestors 'self'From the SEO side the main risk is a policy so strict that it breaks the page. Analytics, a tag manager, a chat widget, fonts from another domain: each must be allowed explicitly or it will not load.
So roll CSP out in stages:
- Turn on
Content-Security-Policy-Report-Only. The browser only reports violations and blocks nothing. - Look in the browser console or in the reports to see which resources violate the policy.
- Add the legitimate sources and drop the ones you do not need.
- Switch the header to
Content-Security-Policy.
Avoid 'unsafe-inline' in script-src without a nonce or hash, because such a policy protects very little. JSON-LD blocks are data rather than executed scripts, so they normally need no nonce. Syntax details are in MDN on CSP, and the markup itself is covered in the JSON-LD guide.
nosniff, Referrer-Policy, Permissions-Policy and frame protection
The remaining headers are simpler, and each closes its own gap.
X-Content-Type-Options
There is one value: X-Content-Type-Options: nosniff. The browser stops guessing a file's type from its content and trusts the Content-Type header. A script or stylesheet served with the wrong type is then blocked, so before enabling it check that the server sends the right types for .js and .css. See MDN.
Referrer-Policy
It controls how much of the address is sent in the Referer header when a visitor follows a link to another site. Modern browsers default to strict-origin-when-cross-origin, which sends only the origin to other domains. Setting it explicitly makes the behaviour predictable. A stricter policy can hide part of the referral data in analytics. More in MDN on Referrer-Policy.
Permissions-Policy
It switches off browser features the site does not use, for example Permissions-Policy: camera=(), microphone=(), geolocation=(). See MDN.
Frame protection
To stop another site from showing your page in a hidden frame, use the frame-ancestors directive in CSP. The older X-Frame-Options: SAMEORIGIN is still supported and works as an extra layer.
X-Robots-Tag: the header that really is about indexing
One HTTP header does affect search directly: X-Robots-Tag. It works like the robots meta tag but travels in HTTP, which makes it usable for non-HTML files such as PDFs. Example:
X-Robots-Tag: noindex, nofollowWhy it belongs in a security conversation: server or CDN settings sometimes add this header to a whole zone, for instance on a staging domain, and it then slips into production. The page looks normal, the HTML contains no noindex, yet it drops out of the index. Google describes it in its robots meta tag and X-Robots-Tag documentation.
The scanner merges directives from meta robots, googlebot, bingbot and X-Robots-Tag: the most restrictive one wins, and a disagreement between the header and the meta tag is reported. If you control crawling through a file rather than a header, see the robots.txt guide.
How to set the headers on your server
Headers are set on the web server, on a CDN or in application code. An nginx example for a server block with HTTPS:
add_header Strict-Transport-Security "max-age=300" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'" always;The always parameter makes nginx add the header to error responses too, not only successful ones. If you use add_header inside a nested location block, headers from the parent level are not inherited there, so repeat them.
After the change the server response should look roughly like this:
HTTP/2 200
content-type: text/html; charset=utf-8
strict-transport-security: max-age=300
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), microphone=(), geolocation=()
content-security-policy-report-only: default-src 'self'On a CDN, headers are usually added with response transformation rules, and in Node or PHP applications through a middleware layer. Whichever way you choose, verify the result on the live address and not only in the configuration.
How to check the headers and what the scanner reports
The simplest method is the command line:
curl -sI https://example.comThe -I flag requests headers only. You can also see them in the Network tab of the browser developer tools. Check more than the home page: try typical templates and error pages too.
A summary of the headers:
| Header | What it does | Typical value | What the scanner looks for |
|---|---|---|---|
| Strict-Transport-Security | Keeps the browser on HTTPS | max-age=31536000; includeSubDomains | missing, weak, subdomains not covered |
| Content-Security-Policy | Limits resource sources | default-src 'self' | missing, report-only only, weak |
| X-Content-Type-Options | Stops MIME sniffing | nosniff | missing |
| Referrer-Policy | Limits address sharing | strict-origin-when-cross-origin | missing or unsafe |
| Permissions-Policy | Disables unused features | camera=(), microphone=() | missing |
| Frame protection | Blocks embedding | frame-ancestors 'self' | missing or weak |
The SEOAudit scanner reads these headers from an ordinary response. It rates missing HSTS, CSP and frame protection as important, and a missing nosniff as informational. It also reports missing HTTPS, a missing HTTP-to-HTTPS redirect, mixed content, certificate problems, cookie flags and headers that disclose server versions. For HSTS the check applies only to HTTPS responses on hostnames, not IP addresses, and frame-ancestors is read from the header only.
One point matters: the scanner is passive. It only reads headers and never tries exploits, so it cannot prove that a site is secure. It is a list of observations, not a certificate. For the SEO part of the same scan see the SEO audit page, and for AI search readiness see AI visibility.
Security headers will not lift pages in results, but they keep visitors on HTTPS, guard against foreign code and cut the risk of a hack that does hurt search presence. Roll them out gradually and test on the live site. A free scan shows which ones are missing.
Frequently asked questions
- Do security headers affect Google rankings?
No documented source lists security headers as a ranking factor, so do not promise position gains. They help indirectly: they keep users on HTTPS, help avoid hacks and mixed content, and a faulty CSP can break how a page renders. Treat them as hygiene, not as a promotion tactic.
- Should I start with HSTS or CSP?
Usually with HTTPS and the HTTP redirect, then HSTS with a short
max-age. CSP is harder, so introduce it throughContent-Security-Policy-Report-Onlyand switch to enforcement later.nosniffand Referrer-Policy are the easiest to add and can go live once you have checked your MIME types.- Can a wrong CSP break my site?
Yes. A policy that is too strict blocks scripts, styles, fonts or embeds, and the page will not work properly. Use report-only mode first, read the browser console, and only then enforce. After every change check the key templates, especially forms and pages with analytics.
- Do I need HSTS preload?
Not necessarily. Preload puts the domain in a list shipped with browsers and works even on the first visit, but it requires a
max-ageof at least one year,includeSubDomainsand thepreloadtoken, and it is hard to reverse. Use it only when every subdomain reliably works over HTTPS.