← Blog  ·  October 2026

HTTP Security Headers: What They Are and How to Monitor Them (2026)

A practical guide to the 6 most important security headers — what each one does, how to add it to nginx/Apache/your app, and why monitoring header changes catches regressions before your security scanner does.

HTTP security headers are response headers your web server sends to browsers. They tell the browser how to behave with your content — whether to allow it in an iframe, how to handle mixed content, which origins can load resources, and more. Getting them right is a one-time effort. The problem is keeping them right.

A deployment can silently remove a header. A CDN configuration change can override your headers. A new nginx config can reset everything to defaults. Without monitoring, you find out weeks later — usually from a security scanner or a bug bounty report.

🔍 Check your headers right now: Free security headers checker — enter any domain and get a letter grade →

The 6 headers that matter most

1. Strict-Transport-Security (HSTS) High impact

Tells browsers to only connect via HTTPS, even if the user types http://. Prevents SSL stripping attacks.

Recommended value:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

max-age=31536000 = 1 year. includeSubDomains covers subdomains. preload adds you to browsers' hardcoded HTTPS list (submit at hstspreload.org).

Add in nginx: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

2. Content-Security-Policy (CSP) High impact

Controls which resources (scripts, styles, images) the browser is allowed to load. Prevents cross-site scripting (XSS) by blocking inline scripts and untrusted origins.

CSP is the most complex header to configure correctly. A simple starting point:

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'

For SPAs with third-party scripts, you'll need to whitelist each source explicitly. Use Content-Security-Policy-Report-Only first to test without blocking.

3. X-Frame-Options Medium impact

Prevents your page from being embedded in an <iframe> on another site — the primary defense against clickjacking attacks.

X-Frame-Options: SAMEORIGIN

SAMEORIGIN allows your own domain to embed the page. DENY blocks all framing. Note: CSP's frame-ancestors directive is the modern replacement, but X-Frame-Options provides broader browser support.

4. X-Content-Type-Options Easy win

Prevents browsers from MIME-sniffing a response away from the declared content type. Stops a class of attack where a file uploaded as an image gets executed as JavaScript.

X-Content-Type-Options: nosniff

This one is trivially easy to add and has essentially no downside. If this header is missing from your site, it's a free fix.

5. Referrer-Policy Easy win

Controls how much referrer information is included in requests. Without this header, navigating from your site to an external link sends your full URL as the referrer — which can leak sensitive URL parameters (tokens, IDs, query strings).

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

This sends the origin (no path) for cross-origin requests and the full URL for same-origin requests. A safe default for most sites.

6. Permissions-Policy Low effort

Formerly Feature-Policy. Controls which browser features your page can use — camera, microphone, geolocation, etc. Limits the blast radius if a malicious third-party script runs on your site.

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

The empty parentheses disable each feature for all origins including your own. Adjust based on your actual feature usage.


How to add them: nginx, Apache, and app-level

nginx

server {
    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    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;
    # CSP — customize for your app
    add_header Content-Security-Policy "default-src 'self'" always;
}

Apache

<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    Header always set X-Frame-Options "SAMEORIGIN"
    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=()"
</IfModule>

Express / Node.js (via Helmet)

import helmet from 'helmet';

app.use(helmet());
// Helmet sets sensible defaults for all major security headers
// Customize specific headers:
app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "https://cdn.example.com"],
  }
}));

Vercel (vercel.json)

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "X-Frame-Options", "value": "SAMEORIGIN" },
        { "key": "X-Content-Type-Options", "value": "nosniff" },
        { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
        { "key": "Strict-Transport-Security", "value": "max-age=63072000; includeSubDomains" }
      ]
    }
  ]
}

Quick reference: header grades

HeaderMissing gradePresent gradeFix time
HSTSFA (with includeSubDomains)5 min
CSPFA (non-trivial) / B (basic)30 min+
X-Frame-OptionsFA (DENY or SAMEORIGIN)2 min
X-Content-Type-OptionsFA (nosniff)2 min
Referrer-PolicyFA (strict-origin)2 min
Permissions-PolicyFA (any value)5 min

Why monitoring header changes matters

Headers are easy to set and just as easy to accidentally remove. Common regression scenarios:

The typical timeline without monitoring: Headers removed Tuesday after a deployment → security scanner runs Sunday → issue reported Monday → headers fixed and redeployed Tuesday. One week of degraded security posture, and that's assuming the scanner catches it.

External header monitoring catches regressions within minutes. The alert goes to email or Slack; the engineer fixes the config and redeploys; the headers are back before users are exposed for any meaningful period.

🔐 HeaderGuard — alerts when your security headers change

HeaderGuard monitors your site's HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy. Get an email the moment any header changes value, disappears, or reappears. $9/month for up to 10 domains.

Join the HeaderGuard waitlist → Check your headers free

← All articles  ·  HeaderGuard  ·  Free security headers checker