Security Headers on Cloudflare — Transform Rules Configuration
Updated April 2026
Cloudflare lets you set security headers at the edge via Transform Rules — no origin server changes needed. Every request gets the headers before it reaches your users.
Scan your Cloudflare site → HeadersFixerThe two approaches
You can set security headers either from your origin server (Nginx, your app) or at the Cloudflare edge via Transform Rules. Edge rules win because they apply even if your origin forgets to send them — and they survive origin changes.
Setting headers via Transform Rules (recommended)
- Cloudflare Dashboard → your domain
- Rules → Transform Rules → Modify Response Header
- Create Rule → name it "Security Headers"
- When: All incoming requests (or use a custom filter)
- Then: Set static — add each header below
| Header name | Value |
|---|---|
| Strict-Transport-Security | max-age=31536000; includeSubDomains |
| X-Frame-Options | SAMEORIGIN |
| X-Content-Type-Options | nosniff |
| Referrer-Policy | strict-origin-when-cross-origin |
| Permissions-Policy | camera=(), microphone=(), geolocation=(), interest-cohort=() |
| Cross-Origin-Opener-Policy | same-origin |
Adding CSP via Transform Rules
CSP values can be long — Cloudflare Transform Rules support up to 4096 characters per header value:
Header name: Content-Security-Policy Value: default-src 'self'; script-src 'self' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self';
Wrangler (Workers config)
If you use Cloudflare Workers, set headers in your Worker script:
export default { async fetch(request, env) { const response = await fetch(request) const newResponse = new Response(response.body, response) newResponse.headers.set('X-Frame-Options', 'SAMEORIGIN') newResponse.headers.set('X-Content-Type-Options', 'nosniff') newResponse.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin') newResponse.headers.set( 'Strict-Transport-Security', 'max-age=31536000; includeSubDomains' ) newResponse.headers.set( 'Permissions-Policy', 'camera=(), microphone=(), geolocation=()' ) return newResponse }
}
HSTS on Cloudflare
Cloudflare has a dedicated HSTS toggle: Dashboard → SSL/TLS → Edge Certificates → HSTS. Use this instead of a Transform Rule for HSTS — it is easier to manage and handles the preload submission correctly.
Why headers sometimes disappear behind Cloudflare
If your origin sets headers but they vanish in production, Cloudflare may be stripping them. Check:
- Cloudflare does not strip security headers by default — but some apps or WAF rules can override them
- If origin and Cloudflare both set the same header, Cloudflare's Transform Rule wins
- Use Header Diff to compare headers fetched directly from origin vs through Cloudflare