The Security Headers That Actually Matter
A handful of HTTP response headers stand between your site and whole categories of attack — protocol downgrades, cross-site scripting, clickjacking, data leakage. They cost nothing, they're usually one line of server or CDN config, and the majority of sites on the internet ship without them. Here are the ones worth setting and what each actually buys you.
HSTS forces HTTPS, Content-Security-Policy controls what's allowed to load
(and stops most XSS), X-Content-Type-Options: nosniff stops MIME sniffing,
X-Frame-Options / CSP frame-ancestors stops clickjacking, and
Referrer-Policy limits what you leak to other sites. Set them once at the server or CDN and
they apply to every response.
Strict-Transport-Security (HSTS)
HSTS tells the browser: “for the next max-age seconds, only ever talk to me over HTTPS, no
exceptions.” After the first time a browser sees this header, it rewrites any http:// link to
your site to https:// before the request leaves the device — closing the brief
insecure window where a plain-HTTP request could be intercepted and downgraded.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000— remember this for a year. Start lower (a day) while you confirm nothing breaks, then raise it.includeSubDomains— applies the rule to every subdomain too. Only add it once you're certain all of them can do HTTPS.preload— opts you into the browser-shipped preload list, so HTTPS is enforced even on a visitor's very first request. Powerful and slow to undo — treat it as close to permanent.
Content-Security-Policy (CSP)
The heavyweight. CSP is an allowlist of where the browser may load resources from — scripts, styles,
images, frames — and it's the single most effective defence against cross-site scripting. If an attacker
manages to inject a <script> pointing at their own server, a good CSP simply refuses to
execute it because that origin isn't on the list.
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'
CSP is also the easiest header to break your own site with, so the universal advice is to start in report-only mode — the browser reports what would have been blocked without actually blocking anything — tune until the reports are clean, then switch to enforcing:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-reports
A modern CSP also makes X-Frame-Options partly redundant via its frame-ancestors
directive (below), and can upgrade insecure requests with upgrade-insecure-requests.
X-Content-Type-Options
One value, no nuance: nosniff. It stops browsers from second-guessing the Content-Type
you declared and “sniffing” a response into something else — the trick behind attacks that get
an image upload or a text file executed as JavaScript. There is no downside; set it everywhere.
X-Content-Type-Options: nosniff
X-Frame-Options / frame-ancestors
These control whether other sites can embed yours in an <iframe>. Without them, an attacker
can load your real page in an invisible frame over their own decoy buttons — clickjacking
— and harvest clicks the user thinks are landing somewhere else.
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY blocks all framing; SAMEORIGIN allows only your own site. The
CSP frame-ancestors directive is the modern, more flexible replacement (it accepts a list of
allowed origins), but setting both covers older browsers too.
Referrer-Policy
When a visitor clicks a link off your site, the browser tells the destination which page they came from via the
Referer header — which can leak full URLs, including ones with tokens or IDs in the path.
Referrer-Policy reins that in. A sensible, widely-used value:
Referrer-Policy: strict-origin-when-cross-origin
That sends the full URL within your own site, just the origin (no path) to other HTTPS sites, and nothing at all when downgrading to HTTP.
Permissions-Policy
Formerly Feature-Policy, this one switches off browser features your site doesn't use — camera, microphone, geolocation, and more — so that injected or embedded content can't quietly reach for them:
Permissions-Policy: geolocation=(), camera=(), microphone=()
Quick reference
| Header | Stops | Sane starting value |
|---|---|---|
Strict-Transport-Security | Protocol downgrade / interception | max-age=31536000; includeSubDomains |
Content-Security-Policy | Cross-site scripting (XSS) | Start in -Report-Only |
X-Content-Type-Options | MIME-sniffing attacks | nosniff |
X-Frame-Options | Clickjacking | DENY or SAMEORIGIN |
Referrer-Policy | URL / referrer leakage | strict-origin-when-cross-origin |
Permissions-Policy | Unwanted feature access | geolocation=(), camera=(), microphone=() |
Set them once, at the edge. Almost every one of these belongs in
your web-server config (Apache Header set, nginx add_header) or your CDN's response-header
settings — not sprinkled through application code. One block, applied to every response, every page.
The exception is CSP, which often needs per-app tuning before you enforce it.
What FatDig shows you
FatDig captures the full set of HTTP and HTTPS response headers a site returns — visible in the headers
section of the Advanced Dig and in the standalone Header Check tool. Scan
them for the names above: a site serving none of them is leaving easy, free hardening on the table, while a site
with HSTS, a real CSP, and nosniff in place is clearly run by someone paying attention. Pair this
with the redirect chain — HSTS and your http→https redirect work
together to keep visitors on TLS from the very first request.
Try it on FatDig: run your domain through Header Check and look for
Strict-Transport-Security and Content-Security-Policy. Missing both? HSTS is a
one-line win you can ship today; CSP is the bigger project worth putting on the roadmap.