Geekflare is supported by our audience. We may earn affiliate commissions from buying links on this site.
In Security Last updated: December 30, 2020
Share on:
Invicti Web Application Security Scanner – the only solution that delivers automatic verification of vulnerabilities with Proof-Based Scanning™.

A step-by-step guide to implementing secure HTTP headers on websites powered by Cloudflare using Cloudflare Workers.

There are many ways to implement HTTP response headers to secure sites from common vulnerabilities, such as XSS, Clickjacking, MIMI sniffing, cross-site injection, and many more. Its widely adopted practice and recommended by OWASP.

Previously, I wrote about implementing headers in a web server like Apache, Nginx, and IIS. However, if you are using Cloudflare to protect and supercharge your sites, you may take advantage of Cloudflare Workers to manipulate the HTTP response headers.

Cloudflare Workers is a serverless platform where you can run JavaScript, C, C++, Rust code. It gets deployed on every Cloudflare data center, which is more than 200 worldwide.

The implementation is very straightforward and flexible. It gives you the flexibility to apply the headers on the entire site, including the subdomain or specific URI with a matching pattern using Regex.

For this demonstration, I’ll be using the code by Scott Helme.

Let’s get it started…👨‍💻

  • Log in to Cloudflare and click on Workers (direct link)

  • Click Create a Worker

  • Copy the worker.js code from GitHub and paste to Script editor
const securityHeaders = {
        "Content-Security-Policy": "upgrade-insecure-requests",
        "Strict-Transport-Security": "max-age=1000",
        "X-Xss-Protection": "1; mode=block",
        "X-Frame-Options": "DENY",
        "X-Content-Type-Options": "nosniff",
        "Referrer-Policy": "strict-origin-when-cross-origin"
    sanitiseHeaders = {
        Server: ""
    removeHeaders = [

async function addHeaders(req) {
    const response = await fetch(req),
        newHeaders = new Headers(response.headers),
        setHeaders = Object.assign({}, securityHeaders, sanitiseHeaders);

    if (newHeaders.has("Content-Type") && !newHeaders.get("Content-Type").includes("text/html")) {
        return new Response(response.body, {
            status: response.status,
            statusText: response.statusText,
            headers: newHeaders

    Object.keys(setHeaders).forEach(name => newHeaders.set(name, setHeaders[name]));

    removeHeaders.forEach(name => newHeaders.delete(name));

    return new Response(response.body, {
        status: response.status,
        statusText: response.statusText,
        headers: newHeaders

addEventListener("fetch", event => event.respondWith(addHeaders(event.request)));

Don’t save yet; you may want to adjust the following headers to meet the requirement.

Content-Security-Policy – if you need to apply your application policy, you can do it here.

Ex – if you need to source content through iFrame on multiple URLs, then you may take advantage of frame-ancestors as below.

"Content-Security-Policy" : "frame-ancestors 'self'",

The above will allow loading the content from,, and self site.

X-Frame-Options – you can change to SAMEORIGIN if you intend to show your site’s content on some page within the same site using iframe.

"X-Frame-Options": "SAMEORIGIN",

Server – you can sanitize the server header here. Put whatever you like.

"Server" : "Geekflare Server",

RemoveHeaders – do you need to remove some headers to hide the versions to mitigate the information leakage vulnerability?

You can do it here.

let removeHeaders = [

Adding new Headers – if you need to pass some custom headers to your applications, you can add them under securityHeaders section as below.

let securityHeaders = {
	"Content-Security-Policy" : "frame-ancestors 'self'",
	"Strict-Transport-Security" : "max-age=1000",
	"X-Xss-Protection" : "1; mode=block",
	"X-Frame-Options" : "SAMEORIGIN",
	"X-Content-Type-Options" : "nosniff",
	"Referrer-Policy" : "strict-origin-when-cross-origin",
        "Custom-Header"  : "Success",

Once you are done adjusting all the headers you require, name the worker, and click Save and Deploy.

Great! the worker is ready, and next, we need to add this to the site where you want to apply the headers. I’ll apply this to my lab site.

  • Go to Cloudflare home/dashboard and select the site.
  • Navigate to the Workers tab >> Add route.
  • Enter the URL in Route; you can apply the Regex here.
  • Select the newly created workers and Save

That’s all; within a second, you will notice all the headers are implemented to the site.

Here is how it looks like from Chrome Dev Tools. You can also test the header through an HTTP header tool.

I don’t know why the Server header is not reflected. I guess Cloudflare is overriding this.

You see, the overall implementation takes ~15 minutes, and no downtime or restart is required like Apache or Nginx. If you are planning to apply this to a production site, I would suggest first testing on a lower environment, or with the help of a route, you can apply on the test pages to verify the results. Once satisfied, push to wherever you want.

This is awesome!

Thanks to Scott for the code.

  • Chandan Kumar
    Chandan Kumar is the founder of Geekflare. He’s helped millions to excel in the digital realm. Passionate about technology, He’s on a mission to explore the world and amplify growth for professionals and businesses.
Thanks to our Sponsors
More great readings on Security
Power Your Business
Some of the tools and services to help your business grow.
  • Invicti uses the Proof-Based Scanning™ to automatically verify the identified vulnerabilities and generate actionable results within just hours.
    Try Invicti
  • Web scraping, residential proxy, proxy manager, web unlocker, search engine crawler, and all you need to collect web data.
    Try Brightdata
  • is an all-in-one work OS to help you manage projects, tasks, work, sales, CRM, operations, workflows, and more.
    Try Monday
  • Intruder is an online vulnerability scanner that finds cyber security weaknesses in your infrastructure, to avoid costly data breaches.
    Try Intruder