Background

There is a possibility that an attacker could find the DNS or the IP address of a origin configured in Cloudflare and connect too it directly, by passing the Cloudflare, WAF and all its protections.

In this article I will breifly discuss about different mechanisms which could be implemented to address the above problem. At the end I will also analyze different solution and come up with the solution that would be the most easiest to implement.

Solutions

1. Whitelist Cloudflare IPs at the origin

Simply create a security group with Cloudflare IPs and attached the SG to the origin (Public Load Balancer). The security group should only allow ingress traffic from Cloudflare IP ranges. This will help to limit connection to the origin only from Cloudflare.

2. Authenticated Origin Pulls

This capability is based on TLS client certificate authentication and will require some changes in your API Gateway or Web Server. It is as same as setting up MLTS between cloudflare and your origin server. Authenticated pulls help to make sure that the requests to the origin server comes from the Cloudflare network. A detailed explanation on how Authenticated Origin Pulls work can be found here.

3. Add a secret header

The secret header mechanism will set a custom header under the request headers when traffic is passing through Cloudflare. Then, it is possible for the origin (Origin, Web Server, API GW) to check if the incoming request consists of this secret header which was set at Cloudflare and reject any requests that does not contain the specified secret header.

3.1 Setting up the secret header using Cloudflare Workers

Deploy a Cloudflare worker which would append a header to the request body. Cloudflare worker code look like below:

async function handleRequest(request){
    const newReq = new Request(request)

    newReq.headers.append('x-chamara-test', 'Hello, from Cloudflare');

    return await fetch(newReq)
}

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

It is also possible to configure the worker to execute the worker code based on different routing requests triggered on URL patterns. i.e We can set the worker code to be executed only when the URL pattern is equal to *.mydomain.com

3.2 Set a secret header using Cloudflare Transform Rules

It is also possible to set a custom header using the Transform Rules feature in Cloudflare. This can be found under zone settings page, in the Rules section. Transform rules can be used to transform traffic that is passed through Cloudflare including Header modifications. With Transform rules we can create HTTP Request Header Modification rule, that will check the hostname of our website and if it contains the hostname i.e mydomain.com and modify the request header to set a static header.

4. Cloudflare Argo Tunnel

from Cloudflare

Cloudflare Tunnel provides you with a secure way to connect your resources to Cloudflare without a publicly routable IP address. With Tunnel, you do not send traffic to an external IP — instead, a lightweight daemon in your infrastructure (cloudflared) creates outbound-only connections to Cloudflare’s global network. Cloudflare Tunnel can connect HTTP web servers, SSH servers, remote desktops, and other protocols safely to Cloudflare. This way, your origins can serve traffic through Cloudflare without being vulnerable to attacks that bypass Cloudflare.

Solution Analysis

There are pros and cons of each solution. The approach #1, whitelisting Cloudflare IPs will make sure that the traffic is originating from Cloudflare but this does not really ensure that the traffic is received from our Cloudflare account. The origin servers will not able to distinguish traffic received from our Cloudflare account vs the attackers Cloudflare account.

The approach #2, authenticated origin pulls will guarantee that the traffic is received from the Cloudflare. This will require us to configure a mechanism at our origin servers to verify the validity of the certificates. Which would require us to implement some custom logic if the origin server we use do not support this type of validation mechanism.

The approach #3 can be implemented in two different ways using Cloudflare Workers or Transform Rules. I think it would be ideal to go with the Transform Rules approach as the Cloudflare Workers under free plan only allows 100k requests per day and if that number exists addition costs may incur. However, this approach is also a valid way to check if the traffic is received through our Cloudflare account.

The approach #4 would also be a good solution but this requires us to install Cloudflare Tunnel Agent in our systems.

Final Thought

Considering the different pros, cons and limitations. I like the approach #3 - Adding secret header (using Transform Rules preferred) in combination with approach #1, which allows ingress traffic only from the Cloudflare IP ranges.