Article

How to Add Security Headers with Cloudflare

Cloudflare can add HTTP security headers without touching your origin, using Response Header Transform Rules in the dashboard. Create a rule that sets HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy and Permissions-Policy on all responses; use the dedicated HSTS panel for Strict-Transport-Security.

By Paul Rudenko, Security ResearcherUpdated Jun 26, 20267 min read

Cloudflare sits in front of your origin server as a reverse proxy, which makes it a convenient place to add HTTP security headers without redeploying or reconfiguring the application behind it. Because every response passes through Cloudflare's edge, you can attach headers like Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, Referrer-Policy and Permissions-Policy to all traffic in one place.

This guide walks through the dashboard features that do this: Response Header Transform Rules for most headers, the dedicated SSL/TLS panel for HSTS, and a short note on Content Security Policy. It assumes your domain is already proxied through Cloudflare (the orange cloud is enabled on the relevant DNS records).

How do I use Response Header Transform Rules?

The primary tool for adding most security headers is a Response Header Transform Rule. In the Cloudflare dashboard, choose your domain, then go to RulesTransform Rules Modify Response Header and create a new rule.

You give the rule a name, define which requests it applies to (most security headers should apply to all incoming requests), and then specify one or more headers to set with static values. Cloudflare adds these headers as responses leave the edge, so they reach the browser regardless of what your origin sends.

Headers worth setting

A solid baseline of static response headers covers the most common protections, with recommended values drawn from the OWASP Secure Headers Project. Set each of these in the rule:

  • X-Content-Type-Options: nosniff — stops browsers from guessing (“sniffing”) a response's content type, which can otherwise turn a benign file into an executable script.
  • X-Frame-Options: SAMEORIGIN — prevents other sites from embedding your pages in an iframe, a defence against clickjacking.
  • Referrer-Policy: strict-origin-when-cross-origin — limits how much of the originating URL is sent to other sites in the referrer header.
  • Permissions-Policy — opts your site out of powerful browser features it does not use, for example geolocation=(), camera=(), microphone=().

When you add a header in the rule editor, choose the option to set the header to a static value, type the header name in one field and the value in the other, and repeat for each header. Save and deploy the rule. Changes propagate across Cloudflare's network within a short time, usually seconds. Because the rule applies at the edge, you do not need to touch your origin's web server configuration at all — useful when you do not control the origin directly, or when it runs on a platform that makes header configuration awkward.

You can scope a Transform Rule with an expression if you need different headers on different paths — for instance, a stricter Permissions-Policy on an admin area, or skipping X-Frame-Options on a page that is meant to be embedded. For a baseline rollout, though, a single rule matching all requests is the simplest and least error-prone starting point.

How do I enable HSTS on Cloudflare?

HTTP Strict-Transport-Security tells browsers to only ever connect to your site over HTTPS, for a duration you specify. You could set it as a static header in a Transform Rule, but Cloudflare provides a dedicated control that is safer and clearer to manage. Go to SSL/TLSEdge Certificates HTTP Strict Transport Security (HSTS) and enable it there.

The panel lets you set the max-age, choose whether to include subdomains, and whether to set the preload flag. Using this control means you have one obvious place to view and change your HSTS policy, and you avoid accidentally sending two conflicting Strict-Transport-Security headers if your origin already emits one. A typical production value is a max-age of one year, written in seconds:

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

Treat HSTS with respect. Once a browser has seen the header, it will refuse plain HTTP to your domain for the entire max-age, and there is no easy way to undo that on a visitor's machine. Enable includeSubDomains only after confirming that every subdomain — including ones you may have forgotten — serves HTTPS correctly. The preload flag goes further still by baking your domain into browsers' built-in HSTS lists, so leave it off until you are fully committed and have verified your setup.

Can Cloudflare add a Content-Security-Policy?

Content-Security-Policy is the most powerful and the most demanding header, because it must enumerate exactly which sources of scripts, styles, images and other resources your pages are allowed to load. You can deliver a CSP through Cloudflare in two ways. The simplest is another Response Header Transform Rule that sets a static Content-Security-Policy value. If your policy needs to be dynamic — for example, generating a fresh nonce per request — a Cloudflare Worker can rewrite responses and inject the header programmatically.

Common gotcha: headers set by Cloudflare at the edge can duplicate headers your origin already sends, so the browser sees two values for the same header. Set each security header in exactly one place — either the origin or Cloudflare, never both. The same caution applies to HSTS: enabling it (especially with includeSubDomains) before every subdomain is fully on HTTPS can lock users out of any subdomain that is not yet served securely.

Whichever method you choose, deploy CSP in report-only mode first. Send Content-Security-Policy-Report-Only instead of the enforcing header, watch what would have been blocked, and tighten the policy gradually until it is clean. Only then switch to the enforcing header. CSP is a deep topic with its own directives, nonces and reporting endpoints; see the Content Security Policy guide for a full walkthrough before you enforce one in production.

Verify the headers reach the browser

After deploying your rules, confirm the headers actually appear on responses. The quickest check from a terminal is a HEAD request with curl, which prints the response headers without downloading the body:

curl -I https://example.com

Look for each header you configured — strict-transport-security, x-content-type-options, x-frame-options, referrer-policy and permissions-policy — and check that each appears exactly once. If you see a header twice, you are almost certainly setting it both at the origin and at Cloudflare; remove it from one side. You can also confirm Cloudflare is in the path by checking for the server: cloudflare and cf-ray headers in the same output. The browser DevTools Network tab shows the same headers on the document request if you prefer a visual check.

Confirm Cloudflare is sending your headers correctly and once each.

Check your security headers

Where to go next

Cloudflare is one of several ways to add these headers. To understand what each header does and why it matters, read the pillar guide, the complete guide to HTTP security headers. If you serve traffic from your own web server instead of relying on the edge, the companion walkthrough adding security headers with Nginx covers the equivalent origin-side configuration.

Frequently asked questions

How do I add security headers in Cloudflare?

Use a Response Header Transform Rule. In the dashboard, open your domain and go to Rules, then Transform Rules, then Modify Response Header, and create a rule. Choose to set a header to a static value, type the header name and value, and add one entry for each header you want. Apply the rule to all requests for a baseline rollout, then save and deploy. Cloudflare attaches the headers as responses leave the edge, so they reach browsers without any change to your origin server. This is ideal when you do not control the origin or it runs on a platform where header configuration is awkward. The one exception is HSTS, which has its own dedicated panel under SSL/TLS rather than a manual header.

Should I set headers at the origin or in Cloudflare?

Pick one place per header and stay consistent. The risk in doing both is duplication: if your origin sends X-Frame-Options and Cloudflare adds it too, the browser receives two values for the same header, which is confusing and can behave unpredictably. Cloudflare is convenient when you cannot easily change the origin or want a single edge-level place to manage headers across several sites. Origin configuration is preferable when your application already generates dynamic, request-specific values such as a per-request CSP nonce. Whichever you choose, verify with curl -I that each header appears exactly once. If you migrate header management from origin to Cloudflare, remove the origin entries at the same time so the two never overlap.

How do I enable HSTS in Cloudflare?

Use the dedicated panel rather than a manual header. Go to SSL/TLS, then Edge Certificates, then HTTP Strict Transport Security (HSTS), and enable it. The panel lets you set max-age, decide whether to include subdomains, and whether to set the preload flag, all in one clear place. A common production value is a max-age of one year, which is 31536000 seconds. Be careful: once a browser has seen the header it refuses plain HTTP for the whole duration, and you cannot easily reverse that on a visitor's machine. Turn on includeSubDomains only after confirming every subdomain serves HTTPS correctly, and leave preload off until you are fully committed and have verified your entire setup end to end.

Can Cloudflare add a Content-Security-Policy?

Yes, in two ways. For a fixed policy, set Content-Security-Policy as a static value in a Response Header Transform Rule, the same way you add other headers. For a dynamic policy, such as one that injects a fresh nonce on every request, use a Cloudflare Worker to rewrite the response and add the header programmatically. Regardless of method, roll out CSP in report-only mode first by sending Content-Security-Policy-Report-Only, observe what would have been blocked, and tighten the policy until it is clean before switching to the enforcing header. CSP is detailed enough to warrant its own guide, so review the Content Security Policy walkthrough before enforcing one on a live site.

Related guides

See your whole external attack surface

One page is a start. The full external scan covers TLS, headers, DNS, exposed files, open services and known-exploited CVEs across your whole domain.

See the full scan →