Four years ago, I wrote a posts about Security Headers. In that post, I mentioned how to set up Security Headers on Cloudflare using a Worker.
Since then, a lot has happened. Nowadays, you can add Transform Rules, which will save you Worker Requests. So — to keep this short — this is how I handle Security Headers in Cloudflare now:
- Got to
Rules>Overview - Click on "Create Rule"
- Select
Response Header Transform Rule - Fill out
Rule name— I simply call it "Security Headers" - Select
All incoming requests - Then, from
Select item, choseSet static
Next, set Header name and value for the headers you want to add.
In my case, it's:
| Header Name | Value |
|---|---|
| Content-Security-Policy | upgrade-insecure-requests |
| Pemissions-Policy | geolocation=(), microphone=(self) |
| Referrer-Policy | strict-origin-when-cross-origin |
| X-Frame-Options | DENY |
A Note on Content Security Policy (CSP)
You might notice my global CSP is quite minimal - it only includes upgrade-insecure-requests. This is intentional. Since my site, browser.style, is a code-sharing platform where different pages have different security requirements, I handle Content Security Policy on a per-page basis using the <meta> tag in the HTML <head>.
Remove Headers
Now, there's also a lot of headers you want to remove. These headers leak information about your infrastructure and internal systems, which isn't necessarily a security vulnerability, but follows the principle of "don't advertise what you don't need to." For these, I've created another Transform Rule. Instead of Set static, select Remove, and repeat for each of these:
Headers to Remove:
via- Reveals intermediary proxy servers and CDN infrastructure in your request chain (e.g., "1.1 varnish"). This tells attackers which proxy software you're using and potential version information.x-cache-hits- Shows cache statistics, revealing how many times content was served from cache. This is internal performance data that visitors don't need to see.x-fastly-request-id- Exposes that you're using Fastly CDN and provides an internal request tracking ID. While not directly exploitable, it reveals your infrastructure stack.x-github-request-id- If you're using GitHub Pages (like I am), this header reveals both that fact and GitHub's internal request tracking ID.x-origin-cache- Reveals your origin server's caching status (HIT/MISS), which is internal infrastructure information.x-proxy-cache- Similar to above, shows proxy layer caching behavior (HIT/MISS/BYPASS), revealing details about your caching architecture.x-timer- Contains internal timing and performance metrics from your CDN, formatted asS{timestamp},{metrics}. This is debugging information that shouldn't be public.
Why remove these? While these headers aren't direct security vulnerabilities, they provide reconnaissance information that attackers can use to fingerprint your infrastructure. Security through obscurity isn't a primary defense, but there's no reason to advertise your complete technology stack to everyone who makes a request.
Give the rule a name, I simply call it "Remove Headers".
Note: Cloudflare may prevent you from removing certain headers like x-cache and x-served-by as they're protected for debugging purposes. That's normal and expected.
Finally, check your headers via curl -I https://your.domain or go to securityheaders.com — Go for A+ ;-)

Top comments (0)