All articles
HTTP security headers explained, and how SecRift scores yours
Security Tips

HTTP security headers explained, and how SecRift scores yours

HTTP security headers are instructions your server sends to the browser - enforce HTTPS, block clickjacking, restrict scripts, limit what leaks in a Referer. None of them touch your certificate or your TLS setup. SecRift audits seven of them independently and tells you exactly which are missing.

A server can have a perfect certificate, modern TLS, and still ship a response that lets any site frame it, run inline scripts through a stray XSS bug, or hand a full Referer URL to whoever it links to. That is what HTTP security headers are for - a set of instructions carried in the response itself, read and enforced by the browser, with nothing to do with the certificate or the transport encryption underneath. This guide covers seven of them, why each is independent of the others, and how SecRift scores what your domain actually sends.

What are HTTP security headers?

HTTP security headers are response headers that tell the browser how to treat the page it just received: force HTTPS on every future request, refuse to be framed by another site, do not guess a file’s type from its content, restrict which scripts are allowed to run, limit what gets disclosed in a Referer, and cap which powerful device features - camera, microphone, geolocation - a page can use.

None of this lives in the certificate, and none of it lives in the TLS handshake. A certificate proves identity. TLS configuration governs the strength of the encrypted channel. Security headers are a third, independent layer - policy the server hands the browser once the connection is already established, on the response itself.

How security headers work

Each header is a self-contained instruction, sent once per response, that the browser applies on its own. There is no negotiation and no fallback to a default that matches what you intended - if the header is absent, the browser falls back to its own baseline behavior, which is rarely as strict as an explicit policy would be.

That independence is exactly why SecRift treats them as seven separate findings instead of one pass/fail bucket. Strict-Transport-Security has nothing to do with whether framing is blocked. A strong Content-Security-Policy does not imply the server also disables MIME sniffing. Each header closes a different, specific class of attack, and a site can be excellent on one and silent on another.

Why they matter

  • Strict-Transport-Security (HSTS). Once a browser sees a valid HSTS header, it upgrades every future request to that domain to HTTPS on its own, even if the user types http:// or clicks a stale link - closing the window an attacker needs for an SSL-stripping downgrade.
  • Content-Security-Policy (CSP). The single strongest defense against cross-site scripting a browser can enforce. A well-built policy restricts which scripts are allowed to run at all, so an injected <script> tag simply does not execute, whatever the vulnerability that let the attacker insert it.
  • Framing protection. X-Frame-Options or CSP’s frame-ancestors stops your page from being loaded inside an invisible frame on someone else’s site - the setup behind clickjacking, where a user thinks they are clicking one thing and is actually clicking yours.
  • X-Content-Type-Options. Setting nosniff stops the browser from guessing a file’s type from its content instead of trusting the declared Content-Type - closing off attacks that smuggle executable content inside a file the server labeled as harmless.
  • Referrer-Policy. Controls how much of the previous URL - including any tokens sitting in the query string - gets handed to every site you link to, in the Referer header of the outgoing request.
  • Permissions-Policy. Restricts which origins can request powerful browser features like camera, microphone, and geolocation, which matters most for pages that embed third-party content.
  • Info leakage and deprecated headers. Server and X-Powered-By version strings hand an attacker a shortlist of CVEs to try first, and headers like X-XSS-Protection, Expect-CT, and Public-Key-Pins are dead weight - ignored by modern browsers, or in HPKP’s case, a header that can lock out your own domain if misconfigured.

Common mistakes

  • Shipping a CSP that looks strict but is not. unsafe-inline in script-src without a matching nonce or hash quietly cancels most of the benefit, and a bare wildcard * or an http:/data: source in script-src does the same.
  • Treating HSTS max-age as a checkbox. A max-age of a few minutes technically sends the header but expires the protection almost immediately - the useful floor is six months, with a full year plus includeSubDomains needed for browser preload lists.
  • Leaving Referrer-Policy unset. Modern browsers default to a reasonably safe value on their own, but an unset header means the site never actually committed to that behavior, and unsafe-url - if anyone still sets it - forwards the full URL even across an HTTPS-to-HTTP downgrade.
  • Publishing a Permissions-Policy that restricts nothing. A policy where every directive is set to * reads like hardening but leaves the default, wide-open allowlist untouched.
  • Keeping headers that browsers no longer honor. X-XSS-Protection and Expect-CT do nothing in current browsers, and Public-Key-Pins was removed everywhere years ago - all three are safe to delete.

How SecRift checks HTTP security headers

SecRift fetches exactly one HTTP response per scan: GET / over HTTPS, following redirects on the same trust boundary as every other web check - HTTPS-only (a downgrade to plain HTTP is treated as a measurement error, not a passing redirect), capped at 10 hops, with each hop guarded against pointing at a private or internal address. If nothing answers on port 443 at all, the check is skipped rather than penalized - there is no response to audit, so it does not count against the score.

Once that final response is in hand, seven independent findings come out of its headers:

  • HSTS - checks for a valid Strict-Transport-Security header and scores it on max-age, includeSubDomains, and preload eligibility.
  • Content-Security-Policy - the heaviest-weighted finding, because a well-built CSP is the strongest single defense against script injection. SecRift evaluates it in the spirit of Google’s CSP Evaluator: whether script-src is restricted with a nonce, hash, or 'strict-dynamic', and whether object-src 'none' and base-uri close off the two classic bypass routes - legacy plugin objects and <base> tag injection.
  • Framing protection - confirms clickjacking is blocked via CSP frame-ancestors or a usable X-Frame-Options value.
  • X-Content-Type-Options - checks for nosniff, exactly as sent.
  • Referrer-Policy - scores the declared value from strict (no-referrer, strict-origin-when-cross-origin) down to the explicitly dangerous unsafe-url.
  • Permissions-Policy - checks whether at least one powerful browser feature is actually restricted, rather than left on a wildcard allowlist.
  • Info leakage - the lightest-weighted, advisory finding: flags version-revealing Server/X-Powered-By values and any of the three deprecated headers still lingering in the response.

Because each finding is independent, a domain can pass CSP and still fail framing protection, or nail HSTS while leaking a server version string - the report shows exactly which of the seven is the weak link, not a single blended verdict. This check audits what the server tells the browser to do once a connection is open, so it sits next to SecRift’s TLS configuration coverage, which audits the encrypted channel itself, and next to security.txt, the other thing your server publishes over HTTP for anyone who asks.

Run a free scan on any domain at secrift.com and see your HTTP security headers posture in seconds.