Comparatifs

Défi géré Cloudflare vs défi interactif

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/.

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

Les commentaires sont désactivés pour cet article.