Skip to content

Commit b341a2c

Browse files
kristianfreemanpatriciasantaana
authored andcommitted
[turnstile] Complete tutorial: integrating Turnstile with Bot Management and WAF (#16784)
* [turnstile] Add tutorial on integrating with WAF/BM * Finish writing + screenshots * Update URL * Apply suggestions from code review * Fix list rendering and bump date --------- Co-authored-by: Patricia Santa Ana <[email protected]>
1 parent 4a7d0b8 commit b341a2c

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-0
lines changed
36.9 KB
Loading
55.5 KB
Loading
67.2 KB
Loading
98.6 KB
Loading
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
---
2+
title: "Integrating Turnstile, WAF, & Bot Management"
3+
pcx_content_type: tutorial
4+
updated: 2024-09-17
5+
difficulty: Beginner
6+
content_type: 📝 Tutorial
7+
tags:
8+
- Turnstile
9+
- Web Application Firewall
10+
- Bot Management
11+
languages:
12+
- JavaScript
13+
sidebar:
14+
order: 3
15+
16+
---
17+
18+
This tutorial will guide you on how to integrate Cloudflare Turnstile, [Web Application Firewall (WAF)](/waf/), and [Bot Management](/bots/get-started/bm-subscription/) into an existing authentication system. This combination creates a robust defense against various threats, including automated attacks and malicious login attempts.
19+
20+
## Overview
21+
22+
To use WAF and Bot Management, your site must have its DNS pointing through Cloudflare. However, Turnstile can be used independently on any site including those not on Cloudflare's network. This tutorial will cover how to implement all three products, but you can focus on Turnstile if your site is not on Cloudflare's network.
23+
24+
WAF, Bot Management, and Turnstile work well together by operating on different layers of the application:
25+
26+
- WAF filters malicious traffic based on network signals.
27+
- Bot Management analyzes requests to identify and mitigate automated threats.
28+
- Turnstile examines client-side and browser signals to distinguish between human users and bots.
29+
30+
By combining server-side (WAF and Bot Management) and client-side (Turnstile) security measures, you can combine multiple layers of defense to create a protection system that is difficult for attackers to circumvent.
31+
32+
## Before you begin
33+
34+
- You must have a Cloudflare account with access to WAF and Bot Management (if using).
35+
- An existing JavaScript/TypeScript-based route handling authentication.
36+
37+
This tutorial uses a simple login form written in plain HTML to demonstrate how to integrate Turnstile into your application. In the backend, a stubbed out authentication route, written in TypeScript, will handle the login request. You may replace this with the language of your choice. As long as your language or framework is able to make an external HTTP request to [Turnstile's API](/api/operations/accounts-turnstile-widget-create), you can integrate Turnstile into your application.
38+
39+
## Configure WAF and Bot Management
40+
41+
If your site is on Cloudflare's network and subscribed to an Enterprise plan, you must configure WAF and Bot Management.
42+
43+
### Issue challenges for potential bot traffic
44+
45+
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and select your account.
46+
2. Go to **Security** > **WAF**.
47+
3. Create a new custom WAF rule by selecting "Edit expression":
48+
- Field: "Bot Score"
49+
- Operator: "less than or equal to"
50+
- Value: "30"
51+
- Action: "Managed Challenge"
52+
53+
54+
This configuration challenges requests with a low bot score, leveraging network signals to identify potential threats before they reach your application. You may customize the score threshold based on your specific use case.
55+
56+
## Set up Cloudflare Turnstile
57+
58+
Turnstile can be used on any site, regardless of whether it is on Cloudflare's network:
59+
60+
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/) and select your account.
61+
2. Go to **Security** > **Turnstile**.
62+
3. Select **Add a widget** and fill out the necessary information.
63+
4. Add your domain to the Turnstile configuration.
64+
5. Select **Create**.
65+
66+
Turnstile adds an extra layer of security by analyzing browser and client-side signals, complementing the server-side checks performed by WAF and Bot Management.
67+
68+
69+
### Enable the option to use the existing clearance cookie
70+
71+
If your site is on Cloudflare, you can enable the option to use the existing [clearance cookie](/turnstile/concepts/pre-clearance-support/) in Turnstile's settings. This integration allows Turnstile to use the clearance cookie as part of its determination of whether a user should receive a challenge. This integration is optional, but recommended if you already are using WAF and Bot Management.
72+
73+
## Integrating Turnstile into Your Application
74+
75+
There are two components to implementing Turnstile into your application: the Turnstile widget and the server-side validation logic.
76+
77+
### Add the Turnstile widget to your login form
78+
79+
Add the Turnstile widget to your existing login form:
80+
81+
```html
82+
<form id="login-form">
83+
<input type="text" id="username" placeholder="Username" required>
84+
<input type="password" id="password" placeholder="Password" required>
85+
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
86+
<button type="submit">Log in</button>
87+
</form>
88+
89+
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
90+
```
91+
92+
Replace `YOUR_SITE_KEY` with your actual Turnstile site key.
93+
94+
95+
## Handle the login request
96+
97+
In your existing authentication route, add Turnstile validation:
98+
99+
```typescript
100+
async function validateTurnstileToken(ip: string, token: string, secret: string): Promise<boolean> {
101+
const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
102+
method: 'POST',
103+
headers: { 'Content-Type': 'application/json' },
104+
body: JSON.stringify({ ip, secret, response: token })
105+
});
106+
107+
const outcome = await response.json();
108+
return outcome.success;
109+
}
110+
111+
// Assume that this is a TypeScript route handler.
112+
// You may replace this with a different implementation,
113+
// based on your language or framework
114+
export async function onRequestPost(context) {
115+
const { request, env } = context;
116+
const { username, password, token } = await request.json();
117+
118+
// Validate Turnstile token
119+
const secretKey = env.TURNSTILE_SECRET_KEY;
120+
const ip = request.headers.get('CF-Connecting-IP');
121+
const turnstileValid = await validateTurnstileToken(ip, token, secretKey);
122+
if (!turnstileValid) {
123+
// Return back to the login page with an error message
124+
return Response.redirect('/login', 302, {
125+
headers: {
126+
'Location': '/login?error=invalid-turnstile-token'
127+
}
128+
});
129+
}
130+
131+
// Perform your existing authentication logic here
132+
const isValidLogin = await checkCredentials(username, password);
133+
134+
if (isValidLogin) {
135+
return new Response(JSON.stringify({ message: 'Login successful' }), {
136+
status: 200,
137+
headers: { 'Content-Type': 'application/json' }
138+
});
139+
} else {
140+
return new Response(JSON.stringify({ error: 'Invalid credentials' }), {
141+
status: 401,
142+
headers: { 'Content-Type': 'application/json' }
143+
});
144+
}
145+
}
146+
147+
async function checkCredentials(username: string, password: string): Promise<boolean> {
148+
// Your existing credential checking logic
149+
}
150+
```
151+
152+
This setup ensures that the Turnstile token is validated on the server-side before proceeding with the login process, adding an extra layer of security based on client-side signals.
153+
154+
## Testing
155+
156+
After deployment, you will want to test your integration. Because your bot score will be low, you will probably not receive a challenge. However, you can add additional rules as needed to force a redirect to the challenge page. Some options to do this are:
157+
158+
1) Add a WAF rule that always forwards your IP address to the challenge page.
159+
2) Add a WAF rule that checks for the presence of a query parameter, such as `?challenge=true`.
160+
161+
## Best practices
162+
163+
1. Always validate the Turnstile token on the server-side before checking credentials.
164+
2. Use environment variables to store sensitive information like your Turnstile secret key.
165+
3. Implement proper error handling and logging to monitor for potential security issues.
166+
167+
By combining Turnstile with WAF and Bot Management, you can create a system that secures your application at the network layer, while also providing an extra layer of protection using client-side signals. This approach makes it significantly more difficult for malicious actors to automate attacks against your login system.
168+
169+
## Resources
170+
171+
If you are interested in customizing Turnstile, refer to the resources below for more information:
172+
173+
- **[Client-side rendering](/turnstile/get-started/client-side-rendering/)**. Learn how to customize how and when Turnstile renders in your user interface, to better fit your application's needs and user experience.
174+
- **[Server-side validation](/turnstile/get-started/server-side-validation/)**. Learn how Turnstile's API works, including request parameters, as well as how to handle different types of responses, including error codes.
175+
- **[Analytics](/turnstile/turnstile-analytics/)**. Learn how to view Turnstile's analytics in the Cloudflare dashboard. This includes metrics on the number of challenges issued, as well as the CSR (Challenge Solve Rate).

0 commit comments

Comments
 (0)