How to Add Missing HTTP Security Headers to Your Website

Security headers are HTTP response headers that instruct browsers how to behave when handling your site's content — preventing clickjacking, MIME sniffing, cross-origin attacks, and information leakage. Most are a single line of config. Here's what each one does and how to add it.

The headers, what they do, and the values to use

X-Content-Type-Options

Purpose: Prevents browsers from MIME-sniffing a response away from the declared content type. Stops certain attacks where a file is uploaded as one type but executed as another.

X-Content-Type-Options: nosniff

This is the only valid value. Always use nosniff.

Referrer-Policy

Purpose: Controls how much referrer information is included when a user navigates from your site to another. Without it, the full URL (including paths and query strings with sensitive data) can be leaked.

Referrer-Policy: strict-origin-when-cross-origin

This sends the full URL as referrer for same-origin requests, and only the origin (no path) for cross-origin requests.

Permissions-Policy

Purpose: Controls which browser features and APIs your page is allowed to use (camera, microphone, geolocation, etc.). Prevents malicious injected scripts from accessing features you don't use.

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

List only the features your site actually uses. Empty () denies access entirely.

X-Frame-Options

Purpose: Prevents your page from being embedded in an iframe on another site (clickjacking defence).

X-Frame-Options: DENY

Or if you need to allow embedding on your own domain:

X-Frame-Options: SAMEORIGIN

Note: If you have a Content-Security-Policy header with a frame-ancestors directive, that takes precedence over X-Frame-Options in modern browsers.

Cross-Origin-Opener-Policy (COOP)

Purpose: Prevents other sites from accessing your window object if they open your page, protecting against cross-origin attacks.

Cross-Origin-Opener-Policy: same-origin

How to add headers — by platform

Cloudflare (Transform Rules)

Security → Transform Rules → Modify Response Header → Add new rule → Add each header as a Set action.

Nginx

add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header X-Frame-Options "DENY" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;

Apache

Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set X-Frame-Options "DENY"
Header always set Cross-Origin-Opener-Policy "same-origin"

Vercel (vercel.json)

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
        { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" },
        { "key": "X-Frame-Options", "value": "DENY" },
        { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" }
      ]
    }
  ]
}

Netlify (netlify.toml)

[[headers]]
  for = "/*"
  [headers.values]
    X-Content-Type-Options = "nosniff"
    Referrer-Policy = "strict-origin-when-cross-origin"
    Permissions-Policy = "camera=(), microphone=(), geolocation=()"
    X-Frame-Options = "DENY"
    Cross-Origin-Opener-Policy = "same-origin"

Verify it worked

Scan your domain at mydomainrisk.com — the Security Headers card will show pass/fail status for each individual header, and your score will update to reflect the fixes.

Check your security headers

MyDomainRisk checks common security headers and explains exactly what's missing — free.

Scan a domain free →