How to add security headers on Cloudflare

Six HTTP response headers cover the standard hardening checklist. Below: what each one does (honestly — one of them is already the browser default), then the exact Cloudflare configuration.

The headers, and what they actually buy you

Strict-Transport-Security max-age=31536000; includeSubDomains
Tells browsers to only ever use HTTPS for this domain (for 1 year). ⚠ includeSubDomains applies the rule to EVERY subdomain — any HTTP-only subdomain (an old intranet host, a device panel) becomes unreachable until the max-age expires; drop that token if you have one. Only meaningful on HTTPS responses — browsers ignore it over HTTP (RFC 6797). Add the preload token only deliberately: preloading is hard to undo (hstspreload.org).
X-Content-Type-Options nosniff
Stops browsers from guessing content types — the only valid value.
X-Frame-Options DENY
Blocks your site from being framed (clickjacking). The modern replacement is CSP frame-ancestors; keeping X-Frame-Options alongside covers older browsers. Use SAMEORIGIN instead if your site frames itself.
Referrer-Policy strict-origin-when-cross-origin
This is already the browser default — setting it makes your policy explicit rather than fixing a hole. Use no-referrer for the strictest option.
Permissions-Policy camera=(), microphone=(), geolocation=()
Disables powerful browser features your site doesn't use. Minimal sane starting set; extend with more features as needed.
Content-Security-Policy (not copy-pasteable — start with Content-Security-Policy-Report-Only)
CSP is site-specific: a canned policy breaks any third-party script or style you load. Start with Content-Security-Policy-Report-Only to observe violations without breaking anything, then tighten into an enforced policy.

On Cloudflare

Dashboard: Rules → Settings → Managed Transforms → toggle "Add security headers"

Adds automatically:
  x-content-type-options: nosniff
  x-frame-options: SAMEORIGIN
  referrer-policy: same-origin
  x-xss-protection: 1; mode=block
  expect-ct: max-age=86400, enforce

For full control: Rules → Create rule → Response Header Transform Rule (set each header yourself)

Set static  Strict-Transport-Security  max-age=31536000; includeSubDomains
Set static  X-Content-Type-Options     nosniff
Set static  X-Frame-Options            DENY
Set static  Referrer-Policy            strict-origin-when-cross-origin
Set static  Permissions-Policy         camera=(), microphone=(), geolocation=()

Cloudflare gotchas worth knowing

  • The Managed Transform's set is dated (Expect-CT is deprecated; X-Frame-Options comes as SAMEORIGIN, not DENY) and it does NOT add HSTS.
  • HSTS has its own dedicated setting: SSL/TLS → Edge Certificates → HTTP Strict Transport Security. Careful: if you later disable HTTPS before the max-age expires, browsers will refuse to load the site.
  • Transform Rules' "Set" operation replaces any header of the same name coming from your origin.

Verified against Cloudflare: Managed Transforms on 2026-07-12.

Check what your site sends today

The full domain report includes your live response headers, so you can verify the change took effect.

Run a domain report →