Avoid Cloudflare bypassing by using secret headers.

Avoid Cloudflare bypassing by using secret headers.

Cloudflare is a network and content delivery provider on the leading edge, but Cloudflare offers more than that, though. Cloudflare acts as an intermediary between a client and a server, using a reverse proxy to mirror and cache websites. By storing web content for delivery on the closest edge server, it is able to optimize loading times.

This intermediary design is also how Cloudflare offers a level of filtration for security. By sitting between the client and the hosting server, it can detect malicious traffic, intercept distributed denial-of-service attacks, deflect attacks from bots, remove bot traffic and limit spam.

One of the biggest problems for Cloudflare users is that somebody may find the IP address of your service and connect directly to it, bypassing Cloudflare and the protections it offers. That might be the case for example if you're using an ALB and configure your domain on Cloudflare. In this article, we are going to see how to avoid this.

Whitelisting Cloudflare IP addresses on your origin

So, the first thing we need to do is limiting connections to our origin only from Cloudflare IP addresses. Since Cloudflare acts as a reverse proxy, traffic on your origin will come from Cloudflare IP addresses.

To do this, we need to edit the security group of our ALB and allow connections to our application port only from Cloudflare IP list.

Adding a secret-header to ensure traffic is coming from your Cloudflare account.

In the previous step, we have restricted connections to our origin from Cloudflare IPs. This ensures that traffic is coming from Cloudflare, but it doesn't ensure that it's going through our Cloudflare account. A hacker could create a new domain on Cloudflare and point it to our origin, and that will bypass Cloudflare protection.

To avoid this, we are going to add a secret header to the requests using a Cloudflare Worker, and reject all connections that don't contain that secret header on our ALB. As long as the header is kept secret, any requests not coming through our Cloudflare account will be rejected.

So, the first thing we need to do is create a new Cloudflare Worker, with the following code.

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
    // Make the headers mutable by re-constructing the Request.
    request = new Request(request)
    request.headers.set(SECRET_NAME, SECRET_KEY)

    return await fetch(request)
}

SECRET_NAME and SECRET_KEY variables are set as Cloudflare Worker Secrets and must remain secret.

Once we created the Cloudflare Worker, we need to create a Cloudflare Route corresponding to our service name and deploy the worker to this route.

After this, the Cloudflare Worker will be injecting the secret header to all the requests.

Now, it's time to control requests on our ALB. To do this, we need to create an ALB listener rule that forwards to our target group only requests that contain the secret header.

For the other requests, we can return a "403: Unauthorized".

And that's all, by leveraging Cloudflare Workers we shown an easy way to avoid bypassing Cloudflare protection.

Jose López
Jose López
2020-03-10 | 3 min read
Share article

More articles