Inconsistent Cloudflare Turnstile Pre-clearance Behavior for Flutter Implementation

What is the name of the domain?

What is the error number?

cf-mitigated=challenge

What is the error message?

cf-mitigated=challenge, despite providing the correct cf_clearance cookie under the same IP address and user agent

What is the issue you’re encountering

Inconsistent Cloudflare Turnstile Pre-clearance Behavior in Flutter WebView Implementation. While our web implementation works consistently, our Flutter mobile WebView implementation occasionally fails despite following the same pre-clearance approach. This creates a frustrating experience for mobile app users.

What steps have you taken to resolve the issue?

We’ve implemented the solution based on the Cloudflare blog post “Integrating Turnstile with the Cloudflare WAF to challenge fetch requests” (https://blog.cloudflare.com/integrating-turnstile-with-the-cloudflare-waf-to-challenge-fetch-requests). Our implementation includes:

  • Showing the Turnstile widget in a WebView when a challenge is needed
  • Extracting the cf_clearance cookie from the WebView’s cookie store after challenge completion
  • Passing this same cf_clearance cookie in the “Cookie” header of subsequent API requests made from the Flutter app
  • Ensuring the exact same user-agent string from the WebView is copied to the API requests
  • Verifying requests come from the same IP address in both the WebView and API requests

What are the steps to reproduce the issue?

  1. Implement Turnstile in a Flutter app using WebView
  2. Complete a Turnstile to get a cf_clearance cookie
  3. Extract the cf_clearance cookie and user-agent from the WebView
  4. Make API requests to the same domain using identical cookies and user-agent
  5. Observe that occasionally, despite having valid cf_clearance credentials, the API requests still response with header cf-mitigated=challenge

The unpredictable nature of the issue makes it difficult to reliably reproduce, as the exact same code path sometimes works perfectly and other times fails. On regular web browsers, this pre-clearance approach works consistently, but in our Flutter implementation, it occasionally fails.

This topic was automatically closed after 15 days. New replies are no longer allowed.