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.
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"
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"
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:
⚠️ 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"
⚠️ 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:
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:
script-src https://www.googletagmanager.com; connect-src https://*.google-analytics.comscript-src https://www.googletagmanager.com; img-src https://www.googletagmanager.com; connect-src https://*.google-analytics.comstyle-src https://fonts.googleapis.com; font-src https://fonts.gstatic.comframe-src https://www.youtube.com; script-src https://www.youtube.comscript-src https://connect.facebook.net; img-src https://www.facebook.comImportant: This list is not exhaustive. You must audit what your site actually loads.
More resources:
If you've used older security scanners, they might complain about these being missing. You can safely ignore them in 2026:
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.