Online Dev Tools

Developer & Security Tools for IT Professionals

Fuel The Infrastructure
Blog

HTTP Security Headers Beyond CSP: HSTS, X-Frame-Options, and Friends


Content-Security-Policy is the headline security header, and rightly so — but it is also the hardest to get right. The good news is that several other response headers deliver meaningful protection for almost no effort: you set a fixed value once and you are done. If you have been putting off security headers because CSP feels daunting, start with these; they are the cheapest wins in web hardening. You can review what a site currently sends with the CSP Analyzer, which parses the security-relevant headers together.

HSTS: force HTTPS and remember it

Strict-Transport-Security tells the browser "only ever talk to this domain over HTTPS, for the next N seconds." Once a browser has seen it, it upgrades every request to HTTPS before sending anything — closing the window where an attacker on the network could intercept an initial http:// request and downgrade it.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

max-age is the memory duration (a year is standard), includeSubDomains extends it to every subdomain, and preload opts into the browser-shipped list so protection applies even on the very first visit. Only add preload when you are confident every subdomain can serve HTTPS — it is hard to undo quickly.

X-Frame-Options / frame-ancestors: stop clickjacking

If your pages can be embedded in an <iframe> on an attacker's site, they can be overlaid with invisible controls that trick users into clicking things they cannot see — clickjacking. X-Frame-Options: DENY (or SAMEORIGIN) forbids framing. The modern equivalent is the CSP directive frame-ancestors 'none', which is more flexible; setting both covers older and newer browsers.

X-Content-Type-Options: no MIME sniffing

X-Content-Type-Options: nosniff stops the browser from second-guessing your declared Content-Type. Without it, a browser might "sniff" a file you served as text and decide it is actually HTML or JavaScript — turning an innocuous upload into an execution vector. It is a single fixed value with no downside; set it everywhere.

Referrer-Policy: stop leaking URLs

By default, when a user clicks a link off your site, the browser sends the full originating URL in the Referer header. If your URLs contain anything sensitive (tokens, IDs, internal paths), you have just leaked it to a third party. Referrer-Policy: strict-origin-when-cross-origin sends only the origin (not the full path) on cross-site requests, which is a sensible default. This is also a reminder to keep secrets out of URLs in the first place.

Permissions-Policy: turn off what you don't use

Permissions-Policy lets you disable browser features your site does not need — camera, microphone, geolocation — so that a compromised or injected script cannot quietly use them:

Permissions-Policy: geolocation=(), camera=(), microphone=()

A sensible starter set

For a typical site, these four-plus headers are safe to set today, no per-page tuning required:

Then tackle CSP separately as the bigger project — the CSP Header Checklist covers that report-only-to-enforcement path, and a pragmatic CSP is easier than it looks. To confirm what you are shipping, run your headers through the CSP Analyzer; when a value in a header is itself a URL you want to inspect, the URL Parser helps.

The takeaway

CSP is worth doing, but do not let it block the easy wins. HSTS, nosniff, anti-framing, and a sane Referrer-Policy are fixed values you set once for a real security improvement — the highest ratio of protection to effort on the whole web platform.

Sources

  1. MDN — HTTP headers — https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
  2. OWASP Secure Headers Project — https://owasp.org/www-project-secure-headers/

Related tools