Cloudflare is famous among developers as a leading CDN to efficiently deliver customer facing Internet content for their applications, but Cloudflare can also be used to verify all incoming requests before they reach your API server, by leveraging Cloudflare workers.
One of our clients, Scoffable, uses exactly this approach to protect their API server from being overloaded with requests that come from untrustworthy sources. They decided to implement Approov as a Cloudflare worker, and they were kind enough to share their code in Github so that other customers could benefit from their work. That’s the kind of customer we have. Thanks Scoffable!
As the Scoffable team describes it in the readme of their project:
There are a couple of reasons for wanting to do this:
1. Prevent abuse of your unauthenticated APIs (scraping, malicious activity etc)
2 . DDoS prevention
Cloudflare benefits from having a huge, geographically distributed network that allows them to absorb DDoS attacks of any scale and to share intelligence collected across all the traffic they handle. Thus they can handle new and evolving threats in real time, and they do this without impacting the latency of your API. You can read about this and other interesting features on this Cloudflare page, but not all the security benefits of using Cloudflare can be applied to an API server, as per their own advice in the section Page Rule Settings where potential conflicts with the Web Application Firewall are discussed.
While Cloudflare may help with blocking some bad traffic to your API server, they cannot guarantee that a request actually comes from a genuine instance of your mobile app and user (even if the user has been authenticated), and it’s here that Approov will help guard your API server. To understand why user authentication is not enough to protect your API server, I recommend that you read about the difference between who and the what is communicating with your API server in this article.
When you use Approov at the edge of your network with a Cloudflare worker to block unwanted requests from arriving at your API server, you reduce your operational costs while simultaneously increasing the availability of your services, thus providing a faster and more positive experience for all your users. This approach is valid to prevent any type of illegitimate request, scraping bots/scripts, fraudulent activity and even application layer DDoS attacks.
Once more Scoffable makes some good arguments in their readme:
The Approov service attests that a device is running a legitimate version of your mobile application and hasn't been tampered with:
1. If the application looks OK, Approov return a token to your mobile application which is then sent over with any request, is validated server side, and the request is processed
2. If the application doesn't look OK, Approov return a legitimate looking token that will fail the server side validation, and the request won't be processed
This means that only your mobile app can talk to your mobile API.
The Approov token returned by the Approov cloud service to the mobile app is a signed JWT token, and the secret used to sign it is only known by the Approov cloud service and your API server or in this case by the Cloudflare worker. This means that the mobile app is never aware of the secret and so it can never know if the Approov token is valid or invalid. This also means if an attacker tries to spoof or tamper with an Approov token it will be detected.
Another very important feature of Approov is the dynamic configuration which allows the developer to configure security policies on the fly and to update the certificate pins without the need to release a new version of their mobile app. You can read more about this at Approov Dynamic Pinning. This means that certificate pinning is made easy for you to manage and maintain thus removing the remaining excuses preventing you from implementing it in your mobile apps!
To implement Approov as a Cloudflare worker you just need to follow the setup instructions in the readme for the Scoffable repository on Github. It is split into 3 steps which are very easy to follow: configuration, deployment and usage.
This step requires that you edit 2 files and replaces values in them.
The first file is the serverless.yml, where you need to replace `INSERT_CF_ACCOUNT_ID` and `INSERT_CF_ZONE_ID` with their respective values.
The second file is the jwt-verifier.js, where you need to replace `SECRET HERE` with the Approov secret which you can retrieve using the Approov CLI tool, by following this example in the Approov docs.
The serverless framework will be used to deploy the Approov token verifier to Cloudflare, and to do it so, it's necessary that some environment variables are defined in your environment:
If you have not set them already, then just grab the values from Cloudflare and define them with:
Time to deploy the Approov token verifier to Cloudflare with:
Now you can confirm in the Cloudflare console, on the workers tab, that the Approov token verifier has been deployed successfully.
The Approov token verifier worker will expect a header named `Device-Token`, but if you want to rename it, just change it on this line of the jwt-verifier.js file.
For each incoming request the Approov token will be verified, and if it fails validation a 403 http status code is returned, otherwise the request is passed on using the rules you have defined in Cloudflare. If you prefer to use another https status code on a validation failure, then just change it on this line of the jwt-verifier.js file.
Cloudflare at the moment of this writing doesn’t support logging from their workers, thus if you want logging you will need to use an external provider, and you can implement it in this function of the jwt-verifier.js file.
Using Cloudflare in front of your API server means that you can now lock it to only accept requests from Cloudflare, and several strategies can be employed here. One simple and effective strategy is to use a very strong cryptographic token, that is only known by the API server and Cloudflare. Another strategy is to follow the steps on the Cloudflare Authenticated Origin Pulls article which will lock your API server to only accept requests with TLS certificates signed by the Cloudflare certificate authority, therefore locking your API server to only accept request from the Cloudflare network.
Thanks to Scoffable we can show you how to easily implement an Approov token verifier as a Cloudflare worker so that requests only pass through to your API server when they have a valid Approov token.
Using Approov with a Cloudflare worker allows your API server to not be directly exposed to the internet, thus protecting it from all types of unauthorized access attempts by locking it to only accept requests from Cloudflare, the ones that passed the Approov verification, saving you on operational costs, while keeping high availability for your users.