Skip to content

HTTP Security Headers Monitoring: CSP, HSTS, CORS Drift

Webalert Team
May 20, 2026
9 min read

HTTP Security Headers Monitoring: CSP, HSTS, CORS Drift

The security audit passed in March. Mozilla Observatory score: A+. HSTS preload submitted. CSP locked down with nonce-based script-src. In June, a CDN migration moved TLS termination to a new edge configuration. Nobody updated the origin header injection. By August, production responses were missing Strict-Transport-Security on 30% of paths, Content-Security-Policy had reverted to a permissive unsafe-inline default from the framework's dev template, and Access-Control-Allow-Origin: * had appeared on the API subdomain after a CORS "quick fix" in a hotfix branch.

The site was up. Uptime was green. SSL certificates were valid. The application had zero CVEs in the dependency scan. The security posture had silently regressed — and the only signal was a researcher's disclosure email.

HTTP security headers are not decorative. They are enforceable browser-side contracts: which scripts may run, whether the site may be framed, whether TLS is mandatory, which origins may call your API. They are also fragile — stripped by misconfigured reverse proxies, overwritten by CDN "optimization" passes, and replaced by framework defaults when deploy templates change.

This guide covers which headers matter in 2026, how they break on deploy, how to monitor them externally, and how monitoring supports SOC 2 and PCI-DSS evidence. By the end you'll have an assertion spec that catches header drift in 60 seconds.


Why Security Headers Strip on Deploy

Headers are set at multiple layers — and the effective response is whichever layer wins last (or first, depending on your stack):

  1. Application — middleware, framework defaults, Helmet.js, django-csp, etc.
  2. Reverse proxy — NGINX add_header, Apache Header set
  3. CDN edge — Cloudflare Transform Rules, CloudFront response headers policy
  4. Load balancer — ALB listener rules

Failure modes:

  • CDN migration — new edge config doesn't replicate custom headers
  • Proxy buffer change — NGINX proxy_hide_header accidentally removes security headers from upstream
  • Framework upgrade — default security middleware disabled or renamed
  • Environment leak — dev config (CSP_REPORT_ONLY=false, permissive CORS) deployed to prod
  • Hotfix bypass — emergency deploy adds Access-Control-Allow-Origin: * and never reverts
  • Static asset path — headers set on / but not on /assets/* served from object storage
  • API subdomainapi.example.com managed separately, drifts from www

External monitoring hits the URLs users and browsers hit — the effective headers, not what your NGINX config file says they should be.


Headers That Matter in 2026

Strict-Transport-Security (HSTS)

Forces HTTPS for future visits. Example:

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

Failure: Header missing after CDN change → SSL stripping attacks possible on first visit.

Assert: Header present on HTTPS responses; max-age >= 31536000 for preload candidates.

See SSL Certificate Expiration Monitoring for the certificate layer.

Content-Security-Policy (CSP)

Controls which resources the browser may load. Example (simplified):

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none';

Too permissive: script-src * or unsafe-inline without nonce → XSS window open.

Too restrictive: Missing domain for analytics CDN → entire site JS broken (users see blank page, not a security alert).

Assert: Presence of header; deny-list assertions (unsafe-eval absent in prod); allow-list for known directives you require (frame-ancestors 'none' or 'self').

X-Frame-Options / frame-ancestors

Prevents clickjacking. Legacy:

X-Frame-Options: DENY

Modern equivalent in CSP: frame-ancestors 'none'.

Failure: Header removed → site embeddable in malicious iframe.

Assert: X-Frame-Options: DENY or SAMEORIGIN, or CSP frame-ancestors none/self.

X-Content-Type-Options

X-Content-Type-Options: nosniff

Stops MIME-type sniffing attacks.

Assert: Value exactly nosniff on HTML and API responses.

Referrer-Policy

Controls referrer leakage:

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

Assert: Present; not unsafe-url in production.

Permissions-Policy (formerly Feature-Policy)

Disables browser features you don't use:

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

Assert: Present on sensitive apps; camera/mic disabled unless required.

Cross-Origin-Opener-Policy (COOP) / Cross-Origin-Embedder-Policy (COEP)

Required for SharedArrayBuffer and some isolation guarantees:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Assert: If you depend on cross-origin isolation, both must be present and consistent.

CORS (Access-Control-*)

API headers:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, OPTIONS

Failure modes:

  • Access-Control-Allow-Origin: * with credentials — browser rejects; or wide open without credentials — data theft from any origin
  • Missing Access-Control-Allow-Origin on API after deploy → frontend CORS errors (often reported as "API down")
  • Overly broad Allow-Methods or Allow-Headers

Assert: Exact origin match (not * in production with cookies); Allow-Origin present on API preflight paths.

Pair with API Rate Limit Monitoring for API surface coverage.


Monitoring Approaches

1) Response header assertions (primary)

External monitor sends GET/HEAD to URL; inspects response headers (not body).

Header Assertion type
HSTS Present; contains max-age=
CSP Present; does not contain unsafe-eval (if policy forbids)
X-Frame-Options Equals DENY or SAMEORIGIN
X-Content-Type-Options Equals nosniff
Referrer-Policy Present; not unsafe-url
CORS Access-Control-Allow-Origin equals https://app.example.com

Store a hash or canonical string of security-relevant headers. Alert on change.

2) Mozilla Observatory / securityheaders.com

Run quarterly scans for letter-grade baselines. Not suitable for per-minute monitoring (rate limits, point-in-time) but good for audit evidence.

3) CI post-deploy gate

After production deploy, script curls top 10 URLs and fails CI if assertions fail. Complements continuous external monitoring.

4) Subdomain matrix

Headers on www, api, app, cdn-origin, and authenticated paths (/dashboard) diverge. Monitor each independently.

5) Static vs dynamic paths

Object-storage-hosted /assets/ may lack headers entirely. Browsers treat script context separately — but HTML pages must have full set.


Compliance Angle

Security-header monitoring is a control auditors ask for:

Evidence pack: 90 days of monitoring logs showing header assertions passed, plus alert records for any drift events and remediation tickets.


Relationship to Other Security Monitoring

Headers are one layer:


Alerting Thresholds That Work

Critical (page)

  • HSTS missing on production HTTPS homepage
  • CSP missing on authenticated app paths
  • Access-Control-Allow-Origin: * appears on API with credentials
  • X-Frame-Options removed from login/dashboard
  • Security header hash changed on payment/checkout paths without change ticket

High (notification)

  • Any security header missing from monitored URL set
  • CSP contains newly added unsafe-inline or unsafe-eval
  • CORS origin widened (specific origin → *)
  • Header set differs between regions (unintended geo split)

Informational

  • Observatory grade dropped from A to B
  • New header added (document intentional)
  • Permissions-Policy tightened (verify no feature breakage)

Use Scheduled Maintenance Windows when intentionally relaxing headers during testing.

See Alert Fatigue: Notifications That Get Acted On.


Per-Header Failure Playbooks (Short)

Symptom Likely cause Fix direction
HSTS gone CDN config swap Re-apply response headers policy at edge
CSP too loose Framework default restored Re-enable Helmet / security middleware
CSP breaks site New third-party script Add nonce or hash to script-src
CORS errors in browser API deploy removed Allow-Origin Restore explicit origin list
Clickjacking report X-Frame-Options dropped Restore DENY + frame-ancestors
API "down" CORS preflight 404 Fix OPTIONS handler + headers

HTTP Security Headers Monitoring Checklist

  • URL matrix: homepage, login, checkout, API root, static HTML
  • HSTS asserted on all HTTPS entry points
  • CSP present; production deny-list for unsafe-eval (if policy requires)
  • X-Frame-Options or CSP frame-ancestors asserted
  • X-Content-Type-Options: nosniff
  • Referrer-Policy present and not unsafe-url
  • CORS: explicit origin, no wildcard with credentials
  • Header hash tracked; alert on change
  • Multi-region probes (CDN geo headers)
  • Post-deploy CI gate on top 10 URLs
  • Quarterly Observatory / securityheaders.com scan for audit evidence
  • Subdomains (api., app.) included
  • Paired with SSL monitoring and sibling deploy-safety posts
  • Maintenance windows for intentional relaxations

How Webalert Helps With HTTP Security Headers Monitoring

Webalert monitors the headers browsers actually receive:

  • HTTP monitoring — Poll production URLs every 1 minute; inspect response headers on every check
  • Header assertions — Configure required headers and expected values: Strict-Transport-Security contains max-age=31536000, X-Frame-Options equals DENY, X-Content-Type-Options equals nosniff
  • Content must not contain — For CSP, assert body/HTML separately; for headers, assert dangerous values absent (Access-Control-Allow-Origin: * on authenticated API)
  • Change detection — Alert when any security header value changes from baseline hash
  • Multi-region checks — Verify headers from EU, US, APAC — catch CDN geo misconfiguration
  • Multi-channel alerts — Email, SMS, Slack, Discord, Microsoft Teams, webhooks
  • Maintenance windows — Suppress during planned CDN experiments
  • 5-minute setup — Add URL, add header rules, assign on-call

Example Webalert checks:

Homepage

  • URL: https://www.example.com/
  • Status: 200
  • Response header Strict-Transport-Security must contain: max-age=
  • Response header X-Content-Type-Options must equal: nosniff
  • Response header X-Frame-Options must equal: DENY

API

  • URL: https://api.example.com/health
  • Response header Access-Control-Allow-Origin must equal: https://app.example.com
  • Response header must not contain wildcard CORS on credentialed paths

See features and pricing for details.


Summary

  • Security headers (HSTS, CSP, X-Frame-Options, CORS, etc.) enforce browser-side security contracts.
  • They strip silently on CDN migrations, proxy misconfig, framework upgrades, and hotfixes — no 5xx, no app errors.
  • Monitor externally with per-URL header assertions, hash-based change detection, and subdomain matrix coverage.
  • Too-loose CSP/CORS is a vulnerability; too-strict is an outage — document your baseline and alert on drift.
  • Compliance audits (SOC 2, PCI-DSS) benefit from continuous assertion logs and drift alerts.
  • Integrate with SSL monitoring, defacement detection, and the deploy-safety trio (sitemap, redirects, headers).

Security posture is not a point-in-time audit score. It's a continuous invariant — headers your users' browsers must see on every response.


Catch security header drift before your next audit — or disclosure — finds it

Start monitoring with Webalert →

See features and pricing. No credit card required.

Monitor your website in under 60 seconds — no credit card required.

Start Free Monitoring

Written by

Webalert Team

The Webalert team is dedicated to helping businesses keep their websites online and their users happy with reliable monitoring solutions.

Ready to Monitor Your Website?

Start monitoring for free with 3 monitors, 10-minute checks, and instant alerts.

Start Free Monitoring