HTTP Security Fundamentals — The Essential Headers Every Site Needs
Every site needs five security headers: Strict-Transport-Security (force HTTPS), X-Content-Type-Options: nosniff (prevent MIME sniffing), X-Frame-Options: SAMEORIGIN (prevent clickjacking), Referrer-Policy (control URL leakage), and Content-Security-Policy (prevent XSS). Set all five in your server config.
Security headers are HTTP response headers that tell browsers how to behave. They prevent entire classes of attacks — XSS, clickjacking, MIME sniffing, protocol downgrade — with one line of server config each. Most sites are missing at least three.
Scan your site for missing headers → HeadersFixerThe five headers every site needs
1. Strict-Transport-Security (HSTS)
Forces browsers to use HTTPS for future requests. Prevents protocol downgrade attacks and cookie hijacking over HTTP.
Strict-Transport-Security: max-age=31536000; includeSubDomains # Nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
2. X-Content-Type-Options
Prevents browsers from guessing the content type. Without this, a browser might execute a text file as JavaScript.
X-Content-Type-Options: nosniff # Nginx: add_header X-Content-Type-Options "nosniff" always;
3. X-Frame-Options
Prevents your page from being embedded in an iframe on another site — blocks clickjacking attacks.
X-Frame-Options: SAMEORIGIN # Nginx: add_header X-Frame-Options "SAMEORIGIN" always;
4. Referrer-Policy
Controls how much URL information is sent when users click links to other sites. Prevents leaking private URL paths to third parties.
Referrer-Policy: strict-origin-when-cross-origin # Nginx: add_header Referrer-Policy "strict-origin-when-cross-origin" always;
5. Content-Security-Policy
The most powerful security header. Controls which resources (scripts, styles, images, fonts) the page can load and from where. Primary XSS defense.
Content-Security-Policy: default-src 'self'; frame-ancestors 'none'; object-src 'none'; # Nginx: add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; object-src 'none';" always;
All five in one Nginx block
server {
listen 443 ssl;
server_name example.com;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" 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;
# CSP requires knowing your resources first — generate with CSPFixer
}
Vercel — vercel.json
{
"headers": [{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}]
}
Check your current headers
curl -sI https://example.com | grep -iE "strict|content-security|x-frame|x-content|referrer|permissions"Scan your live headers → HeadersFixer