Cloudflare propose deux actions de défi que les opérateurs de sites peuvent configurer dans les règles WAF : Managed Challenge et Interactive Challenge. Managed Challenge est une approche moderne et adaptative : Cloudflare décide de la difficulté par visiteur. Le défi interactif est l'option héritée, présentant toujours un CAPTCHA visible. Comprendre la différence détermine quelle méthode CaptchaAI utiliser et à quoi s'attendre lors de l'automatisation.
Comment les distinguer rapidement sur le terrain ?
| Signal observé | Managed Challenge plus probable | Interactive Challenge plus probable |
|---|---|---|
| Expérience utilisateur | Certains visiteurs passent sans voir de widget | Tout visiteur voit un défi explicite |
| Type de page | Page de vérification évolutive ou widget Turnstile contextuel | Pleine page de défi avec interaction obligatoire |
| Code HTTP | Souvent 503 ou flux intermédiaire |
Souvent 403 avec défi visible |
| Logique de traitement | Il faut parfois gérer un passage invisible ou un défi non interactif | Il faut presque toujours résoudre un widget visible |
Comparaison rapide
| Caractéristique | Défi géré | Défi interactif |
|---|---|---|
| Présenté | 2021 | Héritage (avant 2021) |
| Adaptatif ? | Oui (Cloudflare décide par visiteur) | Non (toujours interactif) |
| Pass invisible possible ? | Oui (~90 % des visiteurs passent de manière invisible) | Non (affiche toujours CAPTCHA) |
| Types de défis utilisés | Tourniquet invisible → Défi → JS | CAPTCHA toujours visible |
| Recommandé par Cloudflare ? | Oui (par défaut pour les nouvelles règles) | Non (conservé pour une compatibilité ascendante) |
| Frottage de l'utilisateur | Faible (la plupart passent sans rien voir) | Élevé (nécessite toujours une interaction) |
| Statut HTTP | 503 | 403 |
| Méthode CaptchaAI | turnstile ou cloudflare_challenge |
turnstile |
Défi géré (moderne)
Le défi géré est l'action de défi recommandée par Cloudflare. Il utilise un cadre de décision pour présenter le défi le moins perturbateur possible :
Flux de décision
WAF rule triggers Managed Challenge
↓
Cloudflare evaluates visitor signals:
├─ Browser fingerprint quality
├─ IP reputation score
├─ TLS fingerprint (JA3/JA4)
├─ Request history
├─ Behavioral signals
└─ Device capabilities
↓
Risk assessment → Challenge level selected:
├─ LOW risk → Invisible pass (no visible UI)
├─ MEDIUM risk → Non-interactive Turnstile (background PoW)
├─ HIGH risk → Interactive Turnstile (checkbox/widget)
└─ VERY HIGH risk → JavaScript challenge page (5s wait)
↓
Challenge completed
↓
cf_clearance cookie issued
Ce que vivent les visiteurs
| Type de visiteur | Ce qu'ils voient | Pourcentage |
|---|---|---|
| Navigateur classique, bonne IP | Rien (passe invisible) | ~90% |
| Nouveau navigateur, IP neutre | Brève fileuse | ~5% |
| Signaux suspects | Case à cocher Tourniquet | ~4% |
| Signaux à haut risque | Page "Vérification de votre navigateur..." | ~1% |
Sortie HTML
Les pages de défis gérés utilisent la plateforme de défis de Cloudflare :
<!-- Managed Challenge page (when visible) -->
<body>
<div id="challenge-stage">
<div id="challenge-body-text">
Verifying you are human. This may take a few seconds.
</div>
<!-- Turnstile widget (when rendered) -->
<div class="cf-turnstile"
data-sitekey="0x4AAAAAAAC3DHQhMMQ_Rxrg">
</div>
</div>
<!-- Challenge platform script -->
<script src="/cdn-cgi/challenge-platform/h/g/orchestrate/managed/v1?ray=...">
</script>
</body>
Défi interactif (ancien)
Interactive Challenge présente toujours un CAPTCHA visible avec lequel le visiteur doit interagir. Il n'y a pas de laissez-passer invisible : chaque visiteur le voit et doit relever le défi.
Comment ça marche
WAF rule triggers Interactive Challenge
↓
Full-page CAPTCHA served (HTTP 403)
↓
Visitor must interact with CAPTCHA widget
↓
CAPTCHA solved
↓
cf_clearance cookie issued
Ce que vivent les visiteurs
Chaque visiteur voit un défi pleine page avec un widget de type tourniquet :
<!-- Interactive Challenge page -->
<body>
<div id="challenge-running">
<div class="main-wrapper">
<h2>Please verify you are human</h2>
<!-- Always-visible challenge widget -->
<div class="challenge-widget">
<!-- Checkbox + verification -->
</div>
</div>
</div>
</body>
Pourquoi Cloudflare le décourage
| Problème | Impact |
|---|---|
| Toujours visible | 100% des visiteurs voient l'enjeu |
| Friction plus élevée | Chaque visiteur doit interagir |
| Taux de rebond plus élevé | Les utilisateurs quittent plutôt que de terminer |
| Pas d'adaptation aux risques | Les bons visiteurs connus sont également mis au défi |
| Problèmes d'accessibilité | Chaque visiteur doit terminer l'interaction |
Détection : à quel défi suis-je confronté ?
import requests
import re
def identify_challenge_type(url):
"""Determine if a URL uses Managed or Interactive Challenge."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0",
"Accept": "text/html,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.9",
}
response = requests.get(url, headers=headers, timeout=15, allow_redirects=False)
html = response.text
status = response.status_code
result = {
"url": url,
"status": status,
"challenge_type": None,
"cf_ray": response.headers.get("cf-ray", ""),
"solve_method": None,
}
if status == 200:
# Check for inline Turnstile widget (not a challenge page)
if "cf-turnstile" in html:
result["challenge_type"] = "turnstile_widget"
result["solve_method"] = "turnstile"
else:
result["challenge_type"] = "none"
return result
if status == 503:
# 503 indicates Managed Challenge or IUAM
if "managed" in html or "challenge-platform" in html:
result["challenge_type"] = "managed_challenge"
result["solve_method"] = "turnstile" # Managed renders as Turnstile
elif "jschl" in html:
result["challenge_type"] = "iuam_js_challenge"
result["solve_method"] = "cloudflare_challenge"
else:
result["challenge_type"] = "unknown_503"
return result
if status == 403:
if "challenge" in html.lower():
result["challenge_type"] = "interactive_challenge"
result["solve_method"] = "turnstile"
else:
result["challenge_type"] = "waf_block"
result["solve_method"] = None # Hard block, not solvable
return result
return result
# Usage
info = identify_challenge_type("https://protected-site.com/login")
print(f"Challenge: {info['challenge_type']}")
print(f"Solve with: {info['solve_method']}")
Tableau de détection
| Signal | Défi géré | Défi interactif | IUAM | Bloc WAF |
|---|---|---|---|---|
| Statut HTTP | 503 | 403 | 503 | 403 |
challenge-platform en HTML |
✅ | ✅ | ❌ | ❌ |
Chemin managed dans le script |
✅ | ❌ | ❌ | ❌ |
jschl en HTML |
❌ | ❌ | ✅ | ❌ |
| Affiche toujours le widget | ❌ | ✅ | ❌ | ❌ |
| Pass invisible possible | ✅ | ❌ | ❌ | ❌ |
Résoudre chaque type de défi
Résoudre un défi géré
Les défis gérés s'affichent généralement sous forme de widgets Turnstile. Utilisez la méthode turnstile de CaptchaAI :
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_managed_challenge(url, sitekey=None):
"""Solve Cloudflare Managed Challenge."""
# If sitekey not provided, extract from page
if not sitekey:
import re
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0",
}
page = requests.get(url, headers=headers, timeout=15)
match = re.search(
r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', page.text
)
sitekey = match.group(1) if match else None
if not sitekey:
# No visible Turnstile — try cloudflare_challenge method
return solve_js_challenge(url)
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": sitekey,
"pageurl": url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
def solve_js_challenge(url):
"""Fallback to cloudflare_challenge method."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "cloudflare_challenge",
"sitekey": "managed",
"pageurl": url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
Résoudre un défi interactif
Interactive Challenge affiche toujours un widget visible. Utilisez la même méthode turnstile :
def solve_interactive_challenge(url, sitekey):
"""Solve Cloudflare Interactive Challenge (legacy)."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "turnstile",
"sitekey": sitekey,
"pageurl": url,
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
return result["request"]
raise TimeoutError("Solve timed out")
Node.js (les deux types)
const axios = require("axios");
const API_KEY = "YOUR_API_KEY";
async function solveCloudflareChallenge(url, type = "managed") {
const method = type === "js_challenge" ? "cloudflare_challenge" : "turnstile";
const sitekey =
type === "js_challenge" ? "managed" : await extractSitekey(url);
const submit = await axios.post("https://ocr.captchaai.com/in.php", null, {
params: {
key: API_KEY,
method,
sitekey: sitekey || "managed",
pageurl: url,
json: 1,
},
});
const taskId = submit.data.request;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const result = await axios.get("https://ocr.captchaai.com/res.php", {
params: { key: API_KEY, action: "get", id: taskId, json: 1 },
});
if (result.data.status === 1) {
return result.data.request;
}
}
throw new Error("Solve timed out");
}
async function extractSitekey(url) {
try {
const response = await axios.get(url, {
headers: { "User-Agent": "Mozilla/5.0 Chrome/120.0.0.0" },
validateStatus: () => true,
});
const match = response.data.match(
/data-sitekey=["']([0-9x][A-Za-z0-9_-]+)["']/
);
return match ? match[1] : null;
} catch {
return null;
}
}
Migration d'interactif vers géré
Cloudflare recommande de migrer d'Interactive vers Managed Challenge. Si un site que vous automatisez change :
| Changement | Effet sur l'automatisation |
|---|---|
| Interactif → Géré | Peut commencer à passer de manière invisible (~ 90 % de chances) |
| HTTP 403 → 503 | Mettre à jour les contrôles du code d'état |
| → adaptatif toujours visible | Le widget n'est peut-être pas en HTML |
| Même clé de site | Le code de résolution CaptchaAI reste le même |
| Même sortie cf_clearance | La gestion des cookies reste la même |
Dépannage
| Symptôme | Parce que | Corriger |
|---|---|---|
| 503 sans widget visible | Défi géré réussi de manière invisible | Aucune action nécessaire : vous avez réussi |
| 503 avec "Vérification de votre navigateur" | Géré élevé au défi JS | Utiliser la méthode cloudflare_challenge |
| 403 avec CAPTCHA visible | Défi interactif (ancien) | Utiliser la méthode turnstile |
| 403 sans défi | Bloc WAF, pas un défi | Changer l'adresse IP ou le modèle de demande |
| Le type de défi change de manière aléatoire | Défi géré s’adaptant aux signaux | Gérez à la fois les défis Turnstile et JS |
| cf_clearance d'un type rejeté pour un autre | Différents flux de défis, même domaine | Résolvez le défi qui se présente |
Questions fréquemment posées
Dois-je toujours essayer le Managed Challenge en premier ?
Oui. La plupart des sites utilisent désormais Managed Challenge. Commencez par la méthode turnstile, et revenez à cloudflare_challenge si la page affiche un défi JavaScript (503 avec « Vérification de votre navigateur »).
Un site peut-il utiliser les deux types sur des pages différentes ?
Oui, mais c'est rare. Chaque règle WAF peut avoir une action différente. Une règle peut utiliser Managed Challenge pour /login et Interactive Challenge pour /api/.
Le défi géré a-t-il toujours besoin d'un cookie cf_clearance ?
Oui. Les deux types de défis produisent le même cookie cf_clearance. La gestion des cookies est identique quel que soit le type de challenge.
Et si le Managed Challenge me dépasse de manière invisible ?
Si Managed Challenge décide que votre demande présente un faible risque, il la transmet sans contestation visible. Votre réponse sera un 200 normal avec le contenu de la page. Aucune résolution CaptchaAI n’est nécessaire dans ce cas.
Le défi interactif est-il obsolète ?
Cloudflare ne l'a pas officiellement déconseillé, mais ils recommandent Managed Challenge pour toutes les nouvelles règles. Interactive Challenge reste pour la compatibilité ascendante. Les sites peuvent migrer à tout moment.
Résumé
Le Managed Challenge de Cloudflare sélectionne de manière adaptative la difficulté du défi par visiteur (invisible au défi JS complet), tandis qu'Interactive Challenge présente toujours un CAPTCHA visible. Les deux produisent le même cookie cf_clearance et sont résolus avecCaptchaAI— utilisez turnstile pour la plupart des défis et cloudflare_challenge pour les pages de défi JavaScript. Managed Challenge est la valeur par défaut moderne ; Le défi interactif est un héritage.
Articles connexes
- Vérification de l'intégrité du navigateur Cloudflare vs Captcha
- Cloudflare Challenge vs détection de tourniquet
- Comparaison Geetest et Cloudflare Turnstile