Security Headers

X-Content-Type-Options: nosniff

Difficulty: Easy — safe to add

This header tells the browser: "trust the Content-Type I send you. Don't try to guess the file type."

Why it matters: Without it, some older browsers can be tricked into interpreting a file as executable JavaScript or HTML when it's really an image or PDF.

How to fix:

Nginx: add_header X-Content-Type-Options "nosniff" always;

Apache / .htaccess: Header always set X-Content-Type-Options "nosniff"

cPanel: Add via .htaccess in your public_html folder.

Cloudflare: Rules → Transform Rules → add response header X-Content-Type-Options: nosniff.


X-Frame-Options: SAMEORIGIN

Difficulty: Easy — safe to add

Prevents your website from being embedded inside an iframe on someone else's site. Stops "clickjacking" attacks.

Why it matters: A user thinks they're clicking your button, but they're actually clicking a hidden button on an attacker's overlay.

Note: Use SAMEORIGIN so your own pages can still embed each other. Only use DENY if no legitimate service embeds your site (payment gateways, booking widgets, etc).

How to fix:

Nginx: add_header X-Frame-Options "SAMEORIGIN" always;

Apache / .htaccess: Header always set X-Frame-Options "SAMEORIGIN"


Referrer-Policy

Difficulty: Recommended — safe to add

Controls how much information your site leaks when a visitor clicks a link to go elsewhere.

Why it matters: Without it, browsers can send the full URL (including parameters like ?order_id=12345) to external sites when someone clicks an outbound link.

Recommended value: strict-origin-when-cross-origin

This sends the full URL on same-site links, but only the domain on cross-site links. It's the browser default anyway.

How to fix:

Nginx: add_header Referrer-Policy "strict-origin-when-cross-origin" always;

Apache / .htaccess: Header always set Referrer-Policy "strict-origin-when-cross-origin"


Strict-Transport-Security (HSTS)

Difficulty: Recommended — but verify HTTPS first

Tells browsers: "only connect to this website over HTTPS. Never try HTTP."

Why it matters: Even if your site redirects HTTP to HTTPS, an attacker can intercept the initial HTTP connection before the redirect happens. HSTS eliminates that gap.

Prerequisites — check these first:

  • Your site already redirects HTTP to HTTPS
  • All content loads over HTTPS — no mixed content warnings
  • Your SSL certificate is valid and not expiring soon

⚠️ A warning about includeSubDomains:

The code below includes includeSubDomains. That means HSTS applies to every subdomain — not just www but also mail., dev., shop., or any staging site. If any of those don't have valid HTTPS, HSTS will break them completely until the max-age expires.

Fix: Before adding includeSubDomains, make sure every subdomain has valid HTTPS. If you're not sure, remove ; includeSubDomains from the snippet.

How to fix (safe process):

Step 1 — Start with a short max-age (5 minutes):

Nginx: add_header Strict-Transport-Security "max-age=300; includeSubDomains" always;

Apache / .htaccess: Header always set Strict-Transport-Security "max-age=300; includeSubDomains"

Test thoroughly for 5 minutes.

Step 2 — Increase to one year:

Nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Apache / .htaccess: Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"


⚠️ Content-Security-Policy (CSP)

Difficulty: Advanced — can break your site. Read carefully.

⚠️ Warning: CSP is powerful but dangerous if misconfigured. It can block your own JavaScript, styles, fonts, CDN images, embedded videos, analytics scripts, and more.

Only add this if:

  • Your website handles sensitive data (e-commerce, member logins, online payments, health or legal)
  • You have someone who can test and monitor for blocked resources
  • You understand what third-party scripts and resources your site loads

For a standard brochure or small business website, CSP is not recommended. The risk of breaking something outweighs the benefit.

Why it matters: CSP is the strongest defence against cross-site scripting (XSS) attacks. It lets you whitelist approved sources for scripts, styles, fonts, images, and more.

The safe approach — report-only mode first:

Don't add CSP directly. Use report-only mode. This logs violations without blocking anything:

Nginx: add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report-endpoint" always;

Check your browser console for violations. Once you understand what your site needs, switch to enforcement.

A basic starting policy (no third-party embeds):

Nginx: add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; form-action 'self'" always;

What to add for common services:

  • Google Analytics (GA4): script-src https://www.googletagmanager.com; connect-src https://*.google-analytics.com
  • Google Tag Manager: script-src https://www.googletagmanager.com; img-src https://www.googletagmanager.com; connect-src https://*.google-analytics.com
  • Google Fonts: style-src https://fonts.googleapis.com; font-src https://fonts.gstatic.com
  • YouTube embeds: frame-src https://www.youtube.com; script-src https://www.youtube.com
  • Facebook Pixel: script-src https://connect.facebook.net; img-src https://www.facebook.com

Important: This list is not exhaustive. You must audit what your site actually loads.

More resources:


Headers you can safely skip (Legacy)

If you've used older security scanners, they might complain about these being missing. You can safely ignore them in 2026:

  • X-XSS-Protection: Modern browsers have phased out the old XSS auditing filters because they actually introduced new security vulnerabilities. CSP has completely replaced it.
  • Pragma / Expect-CT: These are deprecated. Certificate Transparency (CT) is now handled automatically by browsers and Certificate Authorities.

How to check if a header is set

Open a terminal and run: curl -I https://yoursite.com

Or open browser DevTools (F12) → Network tab → click any request → look for Response Headers.

Alternatively, use securityheaders.com — it checks all of these and gives you a grade.

© 2020 Webprecision