By server

Security Headers on Cloudflare (Workers & Pages _headers)

3 min read

Two ways to add security headers on Cloudflare: a static _headers file (Cloudflare Pages and Netlify) or a Worker (any site proxied through Cloudflare).

Option A — _headers file (Cloudflare Pages / Netlify)

Put a file named _headers in your build output root (e.g. public/_headers for many frameworks):

/*
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  X-Content-Type-Options: nosniff
  X-Frame-Options: SAMEORIGIN
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: geolocation=(), camera=(), microphone=()
  Cross-Origin-Opener-Policy: same-origin
  Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'

The /* matches every path; the indented lines are the headers. You can add more specific path blocks above /* for per-route overrides.

Option B — Cloudflare Worker

Add headers to every proxied response:

export default {
  async fetch(request, env, ctx) {
    const response = await fetch(request);
    const r = new Response(response.body, response);
    r.headers.set("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
    r.headers.set("X-Content-Type-Options", "nosniff");
    r.headers.set("X-Frame-Options", "SAMEORIGIN");
    r.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
    r.headers.set("Permissions-Policy", "geolocation=(), camera=(), microphone=()");
    r.headers.set("Cross-Origin-Opener-Policy", "same-origin");
    r.headers.set("Content-Security-Policy", "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'");
    return r;
  },
};

Verify

curl -sI https://yourdomain.com | grep -iE 'strict-transport|content-security|x-frame'

Tip: the _headers file is the simplest path for a static site on Cloudflare Pages — no Worker, no quota. Use a Worker when you need logic (per-path policies, nonces) or you’re proxying an origin that isn’t on Pages. Cloudflare’s dashboard “Transform Rules → Modify Response Header” is a third, no-code option.

Open the full version (with copy buttons) ↗

← All recipes