Home › CDN Security › Checklist
CDN Security

CDN Security Headers Checklist: 10 Essential HTTP Headers for Production

By Priya Sharma, Content Delivery Specialist Sep 10, 2026 8 min read Updated for HTTP/2 & HTTP/3

Security headers are your cheapest, most effective browser-level defense. Enforced correctly at the CDN edge, they mitigate clickjacking, XSS, MIME-sniffing, credential leaks, and cross-origin isolation attacks without touching application code. This checklist covers the 10 headers you should enforce in production at the CDN layer, with recommended values, edge implementation patterns, and validation steps.

TL;DR: Enforce security headers at the CDN, not just the origin. Cacheable assets served from edge without headers = unprotected users. Use a CDN Response Headers Policy as the source of truth and keep origin headers as fallback.
CDN Security Headers Enforcement Flow Browser request flows through CDN edge where security headers are injected before response, while origin remains shielded. Browser Validates Headers HSTS • CSP • COOP HTTPS CDN Edge (PoP) Injects & Normalizes Headers add_header + policy override origin miss → origin Origin App / Object Store Fallback headers ✓ Headers cached with object • Consistent for HIT & MISS • No app deploy needed
Enforce headers at the edge: every cached response carries the same browser protections, regardless of origin state.

Why Enforce at the CDN Edge?

Most teams set headers in Nginx or application middleware. That works until the CDN serves a cached object that was stored without those headers, or until an origin node is misconfigured. The CDN is the only layer that sees every client response. If you understand what a CDN is, you know the edge terminates TLS, handles caching, and is the ideal policy enforcement point.

Edge enforcement gives you three advantages: consistency (headers attached on HIT and MISS), agility (change policy in seconds without redeploying the origin), and observability (log and report violations centrally). Pair this with a solid CDN SSL/TLS configuration so HSTS and other transport guarantees are not undermined by weak ciphers or mixed content. For dynamic workloads, edge computing lets you generate per-request nonces for CSP without round-tripping to origin.

Rule of thumb: origin may set headers, but the CDN policy overrides. Never rely on Vary for security headers and never strip them at the edge for performance.

The Checklist: 10 Headers for Production

Apply these to all HTML and authenticated responses. For static assets (images, fonts, JS/CSS), you still need a subset — especially CORP, X-Content-Type-Options, and Cache-Control.

Performance Comparison: Edge vs Origin Processing
Metric Edge Processing Origin Processing Improvement
Latency (p50)8–15 ms120–300 ms15–20x faster
Cache Hit Ratio85–95%N/AReduces origin load
TLS Handshake1–5 ms (nearby PoP)50–150 ms10–30x faster
Bandwidth Cost$0.01–0.04/GB$0.05–0.12/GB3–5x cheaper
Availability99.99% (multi-PoP)99.9% (single DC)10x fewer outages
Header Recommended Production Value Purpose Priority
Strict-Transport-Security max-age=63072000; includeSubDomains; preload Force HTTPS, prevent SSL stripping Critical
Content-Security-Policy default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none' Mitigate XSS, data injection Critical
X-Frame-Options DENY or SAMEORIGIN Block clickjacking (legacy fallback) High
X-Content-Type-Options nosniff Prevent MIME sniffing High
Referrer-Policy strict-origin-when-cross-origin Limit referrer data leakage High
Permissions-Policy camera=(), microphone=(), geolocation=(), interest-cohort=() Disable sensitive browser features Medium
Cross-Origin-Opener-Policy same-origin Isolate browsing context, prevent XS-Leaks High
Cross-Origin-Embedder-Policy require-corp Require CORP/CORS for cross-origin resources Medium
Cross-Origin-Resource-Policy same-site or same-origin Control who can embed your resources Medium
Cache-Control (security-hardened) no-store for sensitive HTML; public, max-age=31536000, immutable for versioned assets Prevent sensitive data caching Critical

1. Strict-Transport-Security (HSTS)

Enforce HTTPS for the entire domain. Use a long max-age (2 years) with includeSubDomains and submit to the preload list. Only send HSTS over HTTPS, never over HTTP. At the CDN, add it on all HTTPS responses and ensure HTTP → HTTPS redirects happen at the edge before any content is served. This complements your CDN security hardening and TLS settings.

2. Content-Security-Policy (CSP)

CSP is the most powerful but most fragile header. Start strict: default-src 'self', block object-src, restrict base-uri and frame-ancestors. Avoid unsafe-inline entirely — use nonces or hashes generated at the edge. For third-party scripts (analytics, payments), explicitly allowlist domains and require SRI. Use report-to / report-uri to collect violations before blocking.

3. X-Frame-Options

Legacy but still valuable. Set DENY by default; use SAMEORIGIN only if you intentionally frame your own pages. Keep it alongside frame-ancestors 'none' in CSP for defense-in-depth. CDNs should strip conflicting values from origin and normalize to one.

4. X-Content-Type-Options: nosniff

Stops browsers from MIME-sniffing responses away from the declared Content-Type. Critical for preventing drive-by XSS via uploaded files. Apply to all responses — HTML, JS, CSS, JSON, and especially user-uploaded assets served via CDN.

5. Referrer-Policy

Controls how much referrer information leaks on navigation. strict-origin-when-cross-origin balances privacy and analytics: same-origin sends full URL, cross-origin sends only origin, and downgrade to HTTP sends nothing. Avoid no-referrer-when-downgrade if you handle sensitive query params.

6. Permissions-Policy

Formerly Feature-Policy. Explicitly disable features you don't use: camera, microphone, geolocation, payment, USB, and interest-cohort=() to opt out of FLoC/Topics. This limits damage if an attacker injects an iframe. Keep the list minimal and audit it quarterly.

7. Cross-Origin-Opener-Policy (COOP)

same-origin ensures a top-level page does not share a browsing context group with cross-origin documents, mitigating XS-Leaks and Spectre-style attacks. Required for crossOriginIsolated if you use SharedArrayBuffer. Pair with COEP.

8. Cross-Origin-Embedder-Policy (COEP)

require-corp forces cross-origin resources to explicitly opt in via CORP or CORS. Combined with COOP, it enables cross-origin isolation. Roll out carefully — third-party images/scripts without CORP will be blocked. Use credentialless as a stepping stone if needed.

9. Cross-Origin-Resource-Policy (CORP)

Set on the resource itself to declare who may load it. For most sites, same-site is the sweet spot; for sensitive assets (user avatars, PDFs), use same-origin. cross-origin is only for truly public CDN assets like open-source fonts.

10. Cache-Control (Security-Focused)

Caching and security intersect. For authenticated HTML, API responses, and account pages: Cache-Control: no-store, private plus Pragma: no-cache and Clear-Site-Data on logout. For immutable versioned assets (e.g., app.abc123.js): public, max-age=31536000, immutable. Never cache sensitive HTML at the edge without private or no-store.

Production Implementation at the Edge

Configure headers in your CDN's response policy, not just in origin Nginx. This ensures HITs are protected. Below are minimal, production-ready examples.

Nginx (origin fallback) + CDN override

# /etc/nginx/conf.d/security-headers.conf
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
add_header Cross-Origin-Resource-Policy "same-site" always;
# CSP with nonce placeholder - replaced at CDN edge
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-$csp_nonce'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'" always;

CloudFront Response Headers Policy (AWS)

// CloudFront -> Policies -> Response headers -> Create
{
  "Name": "SecurityHeaders-Prod",
  "SecurityHeadersConfig": {
    "StrictTransportSecurity": {"Override": true, "IncludeSubdomains": true, "Preload": true, "AccessControlMaxAgeSec": 63072000},
    "ContentTypeOptions": {"Override": true},
    "FrameOptions": {"Override": true, "FrameOption": "DENY"},
    "ReferrerPolicy": {"Override": true, "ReferrerPolicy": "strict-origin-when-cross-origin"},
    "XSSProtection": {"Override": false} // Deprecated - rely on CSP
  },
  "CustomHeadersConfig": {
    "Items": [
      {"Header": "Permissions-Policy", "Value": "camera=(), microphone=(), geolocation=()", "Override": true},
      {"Header": "Cross-Origin-Opener-Policy", "Value": "same-origin", "Override": true},
      {"Header": "Cross-Origin-Embedder-Policy", "Value": "require-corp", "Override": true}
    ]
  }
}

Cloudflare Workers / Fastly VCL (per-request nonce)

addEventListener('fetch', event => {
  const nonce = btoa(crypto.getRandomValues(new Uint8Array(16)));
  let res = await fetch(event.request);
  res = new Response(res.body, res);
  res.headers.set('Content-Security-Policy',
    `default-src 'self'; script-src 'self' 'nonce-${nonce}'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'`);
  res.headers.set('X-Content-Type-Options', 'nosniff');
  return res;
});

Do: Override at Edge

Set Override: true so duplicate origin headers don't create conflicting values. One canonical value per header.

Don't: Use X-XSS-Protection

Deprecated and can introduce new XSS vectors. Modern browsers ignore it. Invest in CSP instead.

Validation, Monitoring & Rollout

Headers are invisible until they break something. Validate continuously:

Review headers quarterly alongside your CDN fundamentals audit. When you add a new subdomain or third-party script, update CSP and CORP policies before the code ships.

Pre-launch check: Test in staging with identical CDN policy. Verify that cached assets, 404 pages, and error pages all carry the headers. Error pages are often served directly from edge and forgotten.

Frequently Asked Questions

Should security headers be set at the origin or CDN edge?

Set them at the CDN edge as the authoritative layer and keep origin headers as fallback. Edge enforcement guarantees consistent headers even for cached assets and shields origin misconfigurations. Use CDN response header policies to override or append.

Will security headers break caching?

No, if you separate concerns. Use Cache-Control for caching and security headers for browser policy. Avoid adding Vary for security headers. Cache security headers with the response at the edge; they do not affect cache keys unless you misconfigure Vary.

Do I still need X-Frame-Options if I have CSP frame-ancestors?

Yes for defense-in-depth. CSP frame-ancestors is the modern standard, but X-Frame-Options is still respected by older browsers and some enterprise proxies. Send both: X-Frame-Options: DENY or SAMEORIGIN and CSP frame-ancestors 'none' or 'self'.

How do I safely roll out a strict CSP without breaking production?

Start with Content-Security-Policy-Report-Only, collect violation reports, allowlist required sources, remove 'unsafe-inline' via nonces or hashes, then enforce. Use the CDN to inject nonces per request and monitor report-uri/report-to endpoints.

References & Standards: OWASP CDN Security · HTTP/2 specification