Security Score 0/100 — Which Headers to Add
A quick guide to adding all 7 security headers to your web server.
Security Score 0/100 — Which Headers to Add
A security score of 0/100 means your site is missing all recommended HTTP security headers. These headers protect your visitors from cross-site scripting (XSS), clickjacking, MIME sniffing attacks, and more. The good news: adding them takes about 10 minutes.
The 7 Security Headers You Need
| Header | What It Does |
|---|---|
| Content-Security-Policy | Controls which resources the browser is allowed to load |
| Strict-Transport-Security | Forces HTTPS for all future visits |
| X-Content-Type-Options | Prevents MIME type sniffing |
| X-Frame-Options | Prevents your site from being embedded in iframes (clickjacking) |
| Referrer-Policy | Controls how much URL info is sent to other sites |
| Permissions-Policy | Restricts browser features (camera, microphone, geolocation) |
| X-XSS-Protection | Legacy XSS filter (still expected by scanners) |
Priority: What to Add First
Start with the highest-impact, lowest-risk headers:
- Strict-Transport-Security — Zero risk if you already use HTTPS. Maximum impact.
- X-Content-Type-Options — One line, no configuration needed, no side effects.
- X-Frame-Options — Unless your site is intentionally embedded in iframes.
- Referrer-Policy — Low risk with
strict-origin-when-cross-origin. - Permissions-Policy — Restrict features you don't use.
- Content-Security-Policy — Highest protection but requires careful testing.
- X-XSS-Protection — Legacy, but easy to add.
Warning: A badly configured Content-Security-Policy can break your site. Start with
Content-Security-Policy-Report-Onlyto test without blocking anything.
Complete Nginx Configuration
Add this inside your server block in your nginx config:
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header X-XSS-Protection "1; mode=block" always;
# Start with report-only CSP, then switch to enforcing
# add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'self';" always;
# Enforcing CSP (uncomment when ready)
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'self';" always;
Then reload nginx:
sudo nginx -t && sudo systemctl reload nginx
Complete Apache Configuration
Add this to your .htaccess file or virtual host config:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set X-XSS-Protection "1; mode=block"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'self';"
</IfModule>
Make sure mod_headers is enabled:
sudo a2enmod headers
sudo systemctl reload apache2
Customizing Content-Security-Policy
The CSP above is strict. Most real sites need to allow external resources. Common additions:
Google Analytics:
script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com;
img-src 'self' data: https://www.google-analytics.com;
connect-src 'self' https://www.google-analytics.com;
Google Fonts:
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
YouTube embeds:
frame-src https://www.youtube.com;
Tip: Open your browser console after adding CSP. Any blocked resource will show a clear error message telling you exactly what directive to update.
Testing Your Headers
After adding headers, verify them:
From the command line:
curl -I https://example.com
Look for each header in the response.
Online tools: - securityheaders.com — Gives you a letter grade (A+ is the goal) - observatory.mozilla.org — More detailed analysis from Mozilla
Tip: After adding all headers, re-run your SiteWatch security scan to see your updated score. Going from 0 to 80+ is entirely realistic with the configuration above.
Common Mistakes
- Adding headers in the wrong location: In nginx,
add_headerin alocationblock overrides headers set in theserverblock. Use thealwaysparameter. - Forgetting
includeSubDomainson HSTS: Without it, subdomains remain vulnerable. - Too-strict CSP breaking the site: Always test with
Content-Security-Policy-Report-Onlyfirst. - Not reloading the web server: Headers won't take effect until you reload.