Cloudflare Worker
DataDome Cloudflare integration detects and protects against bot activity.
This module is dedicated to be used on Cloudflare, using Workers.
Installation
Prerequisites
DATADOME_SERVER_SIDE_KEY
available in your DataDome dashboard,DATADOME_CLIENT_SIDE_KEY
available in your DataDome dashboard.
Protect your traffic
- Connect to your Cloudflare console and go to the Workers & Pages section.
- Click on Create application.
- Click on Create Worker.
- Choose a name for the Worker, for example
worker/datadome.js
and click on Deploy.
- After your DataDome Worker has been deployed, click on Edit code.
- Download our Cloudflare Module and paste the code from
datadome.js
in the Script Editor.
- Fill the server-side key variable value (
DATADOME_LICENSE_KEY
) with the server-side key from your DataDome dashboard - Fill the client-side key variable value (
DATADOME_JS_KEY
) with the client-side key from your DataDome dashboard. - Click on Save and deploy.
- Confirm by clicking on Save and deploy in the popup window.
- Go back to the Worker overview.
- Inside the Triggers section, add your Custom Domains and/or Routes on which you want the DataDome Worker to be set. Refer to Cloudflare documentation on Domains and Routes.
Congrats! You can now see your traffic in your DataDome dashboard.
Configuration
Configuration is done by changing DataDome variables directly inside the datadome.js
script.
Settings
Setting | Description | Required | default |
---|---|---|---|
DATADOME_LICENSE_KEY | Your DataDome server-side key | Yes | "" |
DATADOME_JS_KEY | Your DataDome client-side key | Optional (but recommended) | "" |
DATADOME_JS_TAG_OPTIONS | JSON object describing JStag option | Optional | '{ "ajaxListenerPath": true }’ |
DATADOME_TIMEOUT | The request timeout for the DataDome API, in milliseconds | Optional | 300 |
DATADOME_URL_REGEX | Processes matching URLs only | Optional | null |
DATADOME_URL_REGEX_EXCLUSION | Ignores all matching URLs | Optional | null |
DATADOME_URI_REGEX_EXCLUSION | Will not send traffic associated with static assets | Optional | /.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|js|map)$/i |
DATADOME_IP_FILTERING | Will not send server-side traffic associated to these IPs to DataDome | Optional | null |
DATADOME_JS_URL | URL of the JS tag. Can be changed to include the tag as a first party | Optional | 'https://js.datadome.co/tags.js' |
DATADOME_JS_ENDPOINT | URL of the JS tag endpoint | Optional | "" |
DATADOME_ENABLE_GRAPHQL_SUPPORT | Extract GraphQL operation name and type on request to a /graphql endpoint to improve protection. | Optional | false |
DATADOME_MAXIMUM_BODY_SIZE | The maximum body size in Bytes that can be processed by DataDome in the request to avoid reading huge payloads. | Optional | 25 * 1024 |
DATADOME_ENABLE_REFERRER_RESTORATION | Set to true to restore original referrer when a challenge is passed. | Optional | false |
Caching policy
DataDome module doesn't change the default caching policy.
However, the module adds a tracking cookie on all requests, which may impact some custom policies.
You can use the Worker TTL feature to force a specific caching TTL.
Feel free to contact our support for any specific needs.
FAQ
Can I enable DataDome only for specified IP?
Yes, you can. You need to update the code at the beginning of the function handleRequest
similarly to the below:
async function handleRequest(request) {
try {
if (request.headers.get('cf-connecting-ip') != "1.2.3.4" && request.headers.get('cf-connecting-ip') != "2606:4700:30::681b:938f") {
return await fetch(request);
}
const url = new URL(request.url);
...
DataDome will only process requests incoming from IP 1.2.3.4
or 2606:4700:30::681b:938f
.
How do I get DataDome logs using Logpush?
You can use Workers Trace Events with Logpush to send logs to a destination supported by Logpush (Datadog, Splunk, S3 Bucket…).
Logpush is available to customers on Cloudflare’s Enterprise plan.
Logging from workers is a feature that is available for workers only using version 1.14 (or later) of our module. It’s not possible to get logs from our app.
This can be done only through Cloudflare’s API.
1. Gather your credentials
X-Auth-Email
: the email address of your accountX-Auth-Key
: the value of Global API Key from My Profile → API tokens
ACCOUNT_ID
: the value of the account ID seen in the Websites Overview page
<SERVICE_NAME>
: the name of the existing service that holds the DataDome script
2. Configure Enriched Headers in DataDome Worker script
Fill the DATADOME_LOG_VALUES
value with the names of Enriched Headers as an Array of Strings.
Eg:
var DATADOME_LOG_VALUES = ["X-DataDome-botname", "X-DataDome-isbot", "x-datadomeresponse"];
3. Create a Logpush job to send data to your destination
- Use the cURL command below to create a Logpush job.
- Replace
<ACCOUNT_ID>
,<API_KEY>
,<EMAIL>
with values from step 1. - Set up the
DESTINATION
: follow the documentation here or find an example for sending logs to R2 at Cloudflare's documentation.
- Replace
curl -X POST 'https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/logpush/jobs' \
-H 'X-Auth-Key: <API_KEY>' \
-H 'X-Auth-Email: <EMAIL>' \
-H 'Content-Type: application/json' \
-d '{
"name": "datadome-logs",
"logpull_options": "fields=Event,EventTimestampMs,Outcome,Exceptions,Logs,ScriptName",
"destination_conf": "<DESTINATION>",
"dataset": "workers_trace_events",
"enabled": true
}'| jq .
4. Enable logging on DataDome Worker
- Enable logging on your DataDome Worker by adding the property
logpush = true
to yourwrangler.toml
file.
# Top-level configuration
name = "<SERVICE_NAME>"
main = "src/index.js"
compatibility_date = "2022-07-12"
workers_dev = false
logpush = true
route = { pattern = "example.org/*", zone_name = "example.org" }
An alternative is to set this property using cURL:
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/workers/scripts/<SERVICE_NAME>" \
-H 'X-Auth-Key: <API_KEY>' \
-H 'X-Auth-Email: <EMAIL>' \
--form 'metadata={"main_module": "<SERVICE_NAME>.js", "logpush": true}' \
--form '"<SERVICE_NAME>.js"=@./<SERVICE_NAME>.js;type=application/javascript+module'
5. Receive data
Enriched Headers are now sent to your Logpush destination.
The output will look like
{
"Event":{
"RayID":"780a1e5f7b3f2a33",
"Request":{
"URL":"https://mydomain.co/",
"Method":"GET"
},
"Response":{
"Status":403
}
},
"EventTimestampMs":1672228648886,
"Exceptions":[
],
"Logs":[
{
"Level":"log",
"Message":[
"1;TestBlock;403"
],
"TimestampMs":1672228648902
}
],
"ScriptName":"datadome"
}
The information sent by DataDome is a Log Message
, and is composed of the values set inDATADOME_LOG_VALUES
, in the same order, separated by a semi-colon.
The -
is set when the value is undefined.
"Logs":[{"Level":"log","Message":["TestBlock;1;403"],"TimestampMs":1672228648902}]
How do I chain DataDome Worker with another Cloudflare Worker?
You can bind DataDome Worker with another service using Cloudflare's HTTP Service Bindings.
DataDome Worker calls Worker B
- Have a functioning Worker B. Script example for Worker B:
export default {
async fetch(request, env, ctx) {
return new Response("Hello World!");
}
}
- Bind your DataDome Worker to Worker B using the interface (Workers & Pages > service-name > Settings > Variables > Service Binding) or using Wrangler in the
wrangler.toml
file
name = "worker_datadome"
main = "worker.js"
services = [
{ binding = "WORKER_B", service = "worker_b" }
]
- Inside the DataDome Worker code, replace
activateDataDome();
withactivateDataDome(globalThis.WORKER_B.fetch.bind(globalThis.WORKER_B));
.
Worker A calls DataDome Worker
- Inside the DataDome Worker, modify the line
activateDataDome();
with the fetch function you want to use. - Bind Worker A to the DataDome Worker service, with the name
DATADOME_WORKER
using the interface (Workers & Pages > service-name > Settings > Variables > Service Binding) or using Wrangler in thewrangler.toml
file. - Call the DataDome Worker inside the Worker A code:
export default {
async fetch(request, env, ctx) {
return await env.DATADOME_WORKER.fetch(request);
},
};
How do I restore the Referer
request header after a challenge has been passed?
Referer
request header after a challenge has been passed?After passing a DataDome challenge on browsers other than Firefox, the referrer value is updated to the current URL which can lead to inconsistent results in website analytics.
Since version 1.18.0
, it is possible to restore the Referer
header to its original value for your backend:
- Contact our support team, they will review your requirements and provide you with the best recommendations.
- Set the boolean value of the
DATADOME_ENABLE_REFERRER_RESTORATION
option totrue
.
Updated about 20 hours ago