Updated April 2026

HTTP Security Fundamentals — The Essential Headers Every Site Needs

Quick Answer

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 → HeadersFixer

The 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