Every HTTP response your server sends carries headers — and some of them are instructions that harden the visitor’s browser against attack. Security headers can block script injection, prevent clickjacking, stop MIME sniffing, and strip private information from outbound requests. They cost nothing, require no code changes in most cases, and remain the most underused defense on the modern web. Here are the seven that belong on essentially every site, with examples you can adapt.

Why Security Headers Matter

Browsers enforce these headers on every request, for every visitor, without any JavaScript or plugin involved. A missing header means the browser falls back to its default — permissive — behavior. That makes headers an excellent complement to fixing vulnerabilities in your code: the header blocks the attack even when a bug slips through. They are not a substitute for secure development, but they are reliable defense in depth.

ℹ Deployment tip: Add headers incrementally and test after each one. CSP in particular can break legitimate functionality if it is too strict — use report-only mode first.

1. Content-Security-Policy

Content-Security-Policy (CSP) is the most powerful header on this list. It declares which sources the browser may load scripts, styles, images, fonts, and connections from — and by default blocks everything else, including inline scripts. Because most cross-site scripting (XSS) payloads rely on injecting script that isn’t supposed to be there, a strict CSP neutralizes the attack even when a flaw exists in the application.

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests

A few notes on this example:

Roll CSP out with Content-Security-Policy-Report-Only plus a report-uri or report-to directive, watch the violation reports for a few days, then enforce.

2. Strict-Transport-Security

HTTP Strict Transport Security (HSTS) tells the browser: “for the next max-age seconds, always use HTTPS when talking to this domain — never plain HTTP.” That defeats SSL-stripping attacks where a man-in-the-middle silently downgrades the connection.

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

3. X-Frame-Options

Clickjacking renders your site inside a transparent iframe and tricks visitors into clicking buttons they can’t see. X-Frame-Options prevents framing by other sites:

X-Frame-Options: SAMEORIGIN

Use DENY if no one may frame your pages, or SAMEORIGIN if your own site embeds itself. This header is legacy — the CSP frame-ancestors directive above is the modern equivalent — but both together give coverage across browser generations.

4. X-Content-Type-Options

Browsers normally “sniff” content to guess its type when the declared Content-Type is missing or wrong — a behavior attackers abuse to smuggle executable content past filters. This header stops the guessing:

X-Content-Type-Options: nosniff

There is exactly one valid value, and there is no downside for a site that serves correct content types. Set it everywhere and forget it.

5. Referrer-Policy

When a visitor clicks a link, the browser sends a Referer header showing the page they came from — and if that URL contains tokens, session fragments, or query parameters, you can leak them to third-party sites. Referrer-Policy caps what gets sent:

Referrer-Policy: strict-origin-when-cross-origin

strict-origin-when-cross-origin sends only the origin (no path, no query string) on cross-site requests, sends nothing on HTTPS→HTTP downgrades, and keeps the full referrer within your own site. It’s the sensible default for most sites; no-referrer is the strictest alternative if you want nothing shared at all.

6. Permissions-Policy

Permissions-Policy decides which browser features — camera, microphone, geolocation, USB, payment APIs, and more — a page or its embedded frames may use. Explicitly denying what you don’t use shrinks the attack surface:

Permissions-Policy: camera=(), microphone=(), geolocation=(self), payment=(self), usb=()

The empty list () denies a feature to everyone, including you; (self) allows it for your origin only. Audit the features your site actually needs, allow those for self, and deny the rest — if a third-party script is compromised, it inherits the same restrictions.

7. Cross-Origin-Opener-Policy

Cross-Origin-Opener-Policy (COOP) prevents pages from different origins sharing the same browsing context group — the isolation primitive behind defenses against cross-site leaks and Spectre-class side-channel attacks:

Cross-Origin-Opener-Policy: same-origin

same-origin lets your own origin’s windows cooperate while cutting off cross-origin access. Be cautious with its stricter companions: Cross-Origin-Embedder-Policy: require-corp delivers full cross-origin isolation but breaks loading of third-party resources that haven’t opted in. Adopt COOP first; treat COEP as a deliberate upgrade.

The Seven at a Glance

XSS: CSP · Downgrade attacks: HSTS · Clickjacking: X-Frame-Options / frame-ancestors · MIME sniffing: X-Content-Type-Options · Data leaks: Referrer-Policy · Feature abuse: Permissions-Policy · Cross-origin leaks: COOP

How to Add Headers

Headers are configured where your site is served. Common setups:

nginx — in the server block:

add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'" always;

Note that add_header inside a location block replaces headers inherited from the parent — either repeat them or centralize the configuration.

Apache — in the virtual host or .htaccess:

Header always set X-Content-Type-Options "nosniff"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Cloudflare — use a Transform Rule to add or modify response headers, with the rule scoped to your hostname. On Cloudflare Pages and Workers, headers can also ship with the deployment itself.

💡 Already on a host that doesn’t expose header config? A CDN or reverse proxy in front of your origin can inject headers without touching the origin server.

Testing Your Headers

Verify after every change — headers that fail to apply provide zero protection:

⚠ Test in staging first: HSTS and CSP are the two headers most likely to break a site when misconfigured — HSTS can lock out non-HTTPS subdomains, and CSP can block your own scripts.

Conclusion

Security headers are one of the highest-value, lowest-effort improvements available to any website — a few lines of server configuration that blunt whole categories of attack for every visitor. Start with the low-risk four (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy), then add HSTS, then tackle CSP in report-only mode until you’re confident. Test after each step, and keep testing — a header that silently disappears is a protection you no longer have.