Reviewed October 2026.
At a glance
| Header | A sensible starting value | Care needed |
|---|---|---|
Strict-Transport-Security | max-age=31536000; includeSubDomains | Only once every subdomain serves HTTPS |
Content-Security-Policy | Depends on the site | High: run it in report-only mode first |
X-Content-Type-Options | nosniff | Low |
| Framing control | Content-Security-Policy: frame-ancestors 'self' | List any sites that embed your pages |
Referrer-Policy | strict-origin-when-cross-origin | Low |
Permissions-Policy | camera=(), microphone=(), geolocation=() | Allow the features your pages use |
Set-Cookie | Secure; HttpOnly; SameSite=Lax on session cookies | A cookie that scripts must read cannot be HttpOnly |
Server, X-Powered-By | No version numbers | Low |
Set headers where they reach every response: the web server, the application framework or the CDN. Check error pages and redirects as well as normal pages. On nginx, for example, add_header skips error responses unless you add always, and a block with its own add_header lines drops the ones inherited from the level above.
HSTS, framing control and a report-only CSP work only as real HTTP headers. Browsers ignore them in an HTML <meta> tag.
Strict-Transport-Security (HSTS)
HSTS (RFC 6797) tells a browser to use only HTTPS for your site for max-age seconds. Browsers ignore the header on plain HTTP responses, so send it over HTTPS and redirect HTTP to HTTPS separately. While the policy lasts, a certificate warning on your site cannot be clicked through.
max-age=31536000is one year. Ironfang reports a max-age under six months, because the protection lapses for occasional visitors.includeSubDomainsextends the policy to every subdomain. Add it only when every subdomain, including internal tools and old services, serves valid HTTPS.- If unsure, ramp up: hstspreload.org suggests five minutes, then a week, then a month, before a long max-age.
max-age=0withdraws the policy, but only for browsers that receive it over HTTPS.
Preloading
HSTS cannot protect a browser's first visit, before it has seen the header. The preload list closes that gap: browsers ship with a list of domains that are HTTPS-only from the start. To join, hstspreload.org requires a valid certificate, a redirect from HTTP to HTTPS on the same host, HTTPS on every subdomain, and a header with a max-age of at least one year, includeSubDomains and preload. Removal takes months to reach users, so preload only when every name under the domain will stay on HTTPS.
- HSTS checker Check Strict-Transport-Security: max-age, includeSubDomains, preload and the HTTP redirect.
Findings and fixes are in the HSTS check reference. The redirect and certificates behind HSTS are covered in TLS and certificates.
Content-Security-Policy
A Content Security Policy tells the browser which scripts, styles, frames and other resources a page may load and run. Its main job is to limit the damage of cross-site scripting: an injected script the policy does not allow does not run. It is a second line of defence, not a fix for the bug that let the script in.
There is no single correct value, because the policy has to match what your pages load. MDN recommends a strict policy based on nonces or hashes rather than a list of allowed hosts, because host lists are hard to get right and often allow more than intended. A nonce-based strict policy:
Content-Security-Policy: script-src 'nonce-{random}'; object-src 'none'; base-uri 'none'
- The server generates a new random nonce for every response and adds it to each legitimate
<script>tag. A static site can list hashes of its scripts instead. 'strict-dynamic'lets a trusted script load further scripts, which helps with tag managers and third-party widgets.'unsafe-inline'inscript-srcwithout a nonce or hash removes most of the protection. Ironfang reports it.frame-ancestorscontrols who may frame the page; see framing control below.
For a simple site with no third-party scripts, default-src 'self' plus the extra sources you need is a reasonable first policy. Either way, start with Content-Security-Policy-Report-Only: the browser reports what it would have blocked without blocking it. Send the reports to an endpoint with report-to, fix or allow what is legitimate, and enforce once the reports are quiet.
- Content Security Policy checker Read a site's Content-Security-Policy directive by directive and spot unsafe inline scripts.
Findings and fixes are in the Content Security Policy check reference.
X-Content-Type-Options
X-Content-Type-Options: nosniff stops browsers guessing a response's type from its content. A script or stylesheet served with the wrong type is blocked, and other responses are treated as the type the server declared. Send it on every response, and make sure every response carries a correct Content-Type.
Findings and fixes are in the X-Content-Type-Options check reference.
Framing control
Clickjacking loads your page in an invisible frame on another site and tricks visitors into clicking it. Control who may frame your pages with the CSP frame-ancestors directive.
frame-ancestors 'none': nobody, including your own site.frame-ancestors 'self': your own origin only.frame-ancestors 'self' https://partner.example: your origin and the sites you name.
X-Frame-Options is the older header, with DENY and SAMEORIGIN; its ALLOW-FROM value is obsolete and modern browsers ignore it. frame-ancestors supersedes it, but sending both does no harm and covers older browsers.
- Clickjacking protection checker See whether other sites can frame a page: CSP frame-ancestors and X-Frame-Options.
Findings and fixes are in the clickjacking protection check reference.
Referrer-Policy
When a visitor follows a link or a page loads a resource, the browser may send the page's address in the Referer header, and full URLs can carry search terms, tokens or identifiers. strict-origin-when-cross-origin sends the full URL within your own site, only the origin to other HTTPS sites, and nothing to plain HTTP. It is the browser default when no policy is set; setting it explicitly keeps it fixed. no-referrer and same-origin share less. Avoid unsafe-url, which sends full URLs everywhere.
Findings and fixes are in the Referrer-Policy check reference.
Permissions-Policy
Permissions-Policy switches off browser features your pages do not use, such as the camera, microphone and location, so that injected or third-party code cannot use them either. camera=() disables a feature everywhere; geolocation=(self) allows it on your own origin only. Browser support is uneven, and MDN marks the header experimental, so treat it as a cheap extra layer rather than a control to rely on.
Findings and fixes are in the Permissions-Policy check reference.
Cookies
Cookie attributes are set in the Set-Cookie header, one cookie at a time. For session and authentication cookies:
Secure: sent only over HTTPS. Set it on every cookie a site served over HTTPS sets.HttpOnly: not readable from JavaScript, so a cross-site scripting bug cannot read the session. Leave it off only for cookies a script genuinely needs.SameSite=LaxorStrict: limits when the cookie is sent with requests started by other sites, which protects against cross-site request forgery.SameSite=Nonesends it everywhere and requiresSecure. Browsers differ in how they treat a cookie without the attribute, so set it explicitly.- No
Domainattribute unless subdomains need the cookie. Without it the cookie goes only to the host that set it; with it, every subdomain receives it. - The
__Host-name prefix makes the browser enforce this: such a cookie must beSecure, havePath=/and have noDomain.
A session cookie set this way: Set-Cookie: __Host-session=<value>; Secure; HttpOnly; SameSite=Lax; Path=/
- Cookie security checker Check the Secure, HttpOnly and SameSite attributes of the cookies a home page sets.
Findings and fixes are in the cookie security check reference.
Version disclosure and retired headers
Server and X-Powered-By often announce the exact software and version behind a site, which lets automated tools match it against known vulnerabilities. Remove the version: server_tokens off; in nginx, ServerTokens Prod and ServerSignature Off in Apache, expose_php = Off in PHP, and turn off X-Powered-By in your framework. This removes a free signal but fixes nothing; keeping the software supported and updated matters far more.
X-XSS-Protection switched on a cross-site scripting filter in older browsers. It is deprecated, and MDN notes that it can create vulnerabilities in otherwise safe sites. Do not add it; if something already sends it, OWASP recommends X-XSS-Protection: 0. A Content Security Policy is the replacement.
- Technology detector See the web server, CDN and frameworks a site's home page discloses.
- End-of-life software checker See whether a site advertises software versions that no longer receive security fixes.
Findings and fixes are in the server information disclosure check reference.
Checking your headers
- HTTP security headers checker Check a site's HSTS, CSP, framing, content-type, referrer and permissions headers.
A check sees the responses to the requests it makes. Headers set in application code can differ from page to page, so also look at the login page, application routes and error pages in your browser's developer tools.
What a check can show, and what it cannot
Ironfang can check
- Which security headers a response carries, and their values
- The HSTS max-age, and whether a CSP allows unsafe inline scripts
- The attributes of cookies the site sets
- Software versions disclosed in headers
The organisation must establish
- That the headers apply to every page, including signed-in areas a check cannot reach
- Which third-party scripts the site needs, and who decides to add one
- Who reads the CSP reports
- That the software behind any disclosed version is supported and updated
The External Security Check runs the header checks on a verified domain with the DNS, email and TLS checks, keeps the results with the domain's history, and can recheck on a schedule.
Sources
Checked on the review date above. Standards and schemes change; the source is the authority.
- RFC 6797: HTTP Strict Transport Security (HSTS)
- HSTS Preload List submission requirements
- MDN: Strict-Transport-Security
- MDN: Content Security Policy (CSP)
- MDN: X-Content-Type-Options
- MDN: CSP frame-ancestors
- MDN: X-Frame-Options
- MDN: Referrer-Policy
- MDN: Permissions-Policy
- MDN: Set-Cookie
- MDN: X-XSS-Protection
- OWASP: HTTP Security Response Headers Cheat Sheet
- nginx: ngx_http_headers_module (add_header)

