Cloudflare ofrece dos acciones de challenge que los operadores del sitio pueden configurar en reglas WAF: Managed Challenge y Interactive Challenge. Managed Challenge es un enfoque moderno y adaptable: Cloudflare decide la dificultad por visitante. Interactive Challenge es la opción heredada y siempre presenta un CAPTCHA visible. Entender la diferencia determina qué método de CaptchaAI usar y qué esperar durante la automatización.
Comparación rápida
| Característica | Desafío gestionado | Desafío interactivo |
|---|---|---|
| Presentado | 2021 | Legado (anterior a 2021) |
| ¿Adaptable? | Sí (Cloudflare decide por visitante) | No (siempre interactivo) |
| ¿Es posible el pase invisible? | Sí (~90 % de los visitantes pasan de forma invisible) | No (siempre muestra CAPTCHA) |
| Tipos de challenge utilizados | Turnstile invisible → Challenge → JS | CAPTCHA siempre visible |
| ¿Recomendado por Cloudflare? | Sí (predeterminado para reglas nuevas) | No (se mantiene por compatibilidad con versiones anteriores) |
| Fricción del usuario | Bajo (la mayoría pasa sin ver nada) | Alto (siempre requiere interacción) |
| Estado HTTP | 503 | 403 |
| Método CaptchaAI | turnstile o cloudflare_challenge |
turnstile |
Desafío gestionado (moderno)
Managed Challenge es la acción de desafío recomendada por Cloudflare. Utiliza un marco de decisión para presentar el desafío menos disruptivo posible:
Flujo de decisiones
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
↓
qa_validation_cookie cookie issued
Lo que experimentan los visitantes
| Tipo de visitante | Lo que ve | Porcentaje |
|---|---|---|
| Navegador normal, buena IP | Nada (pase invisible) | ~90% |
| Navegador nuevo, IP neutra | Breve spinner | ~5% |
| Señales sospechosas | Casilla de verificación de Turnstile | ~4% |
| Señales de alto riesgo | Página "Comprobando tu navegador..." | ~1% |
Detector rápido en Python
import requests
def detect_cloudflare_challenge(url: str) -> str:
html = requests.get(url, timeout=15).text
if "cf-turnstile" in html:
return "interactive-turnstile"
if "/cdn-cgi/challenge-platform/" in html or "challenge-platform" in html:
return "managed-challenge"
if "qa_validation_cookie" in html:
return "already-cleared"
return "no-challenge"
checkout HTML
Las páginas de Managed Challenge usan la plataforma de challenge 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>
Interactive Challenge (heredado)
Interactive Challenge siempre presenta un CAPTCHA visible con el que el visitante debe interactuar. No existe pase invisible: cada visitante ve y debe completar el challenge.
Cómo funciona
WAF rule triggers Interactive Challenge
↓
Full-page CAPTCHA served (HTTP 403)
↓
Visitor must interact with CAPTCHA widget
↓
CAPTCHA solved
↓
qa_validation_cookie cookie issued
Lo que experimentan los visitantes
Cada visitante ve un desafío de página completa con un widget similar a Turnstile:
<!-- 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>
Por qué Cloudflare lo desaconseja
| Problema | Impacto |
|---|---|
| Siempre visible | El 100% de los visitantes ven el challenge |
| Mayor fricción | Cada visitante debe interactuar |
| Mayor tasa de rebote | Los usuarios abandonan en lugar de completar |
| Sin adaptación al riesgo | Los visitantes de buena reputación también son retados |
| Accesibilidad | Cada visitante debe completar la interacción |
Detección: ¿A qué desafío me enfrento?
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']}")
Tabla de detección
| señal | Desafío gestionado | Desafío interactivo | IUAM | Bloque WAF |
|---|---|---|---|---|
| Estado HTTP | 503 | 403 | 503 | 403 |
challenge-platform en HTML |
✅ | ✅ | ❌ | ❌ |
Ruta managed en script |
✅ | ❌ | ❌ | ❌ |
jschl en HTML |
❌ | ❌ | ✅ | ❌ |
| Siempre muestra el widget | ❌ | ✅ | ❌ | ❌ |
| Pase invisible posible | ✅ | ❌ | ❌ | ❌ |
Resolviendo cada tipo de desafío
Resolviendo el desafío gestionado
Los desafíos administrados generalmente se representan como widgets de torniquete. Utilice el método 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")
Resolviendo el desafío interactivo
Interactive Challenge siempre muestra un widget visible. Utilice el mismo método 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 (ambos tipos)
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;
}
}
Migración de interactivo a administrado
Cloudflare recomienda migrar de Interactive a Managed Challenge. Si un sitio que está automatizando cambia:
| Cambiar | Efecto sobre la automatización |
|---|---|
| Interactivo → Gestionado | Puede comenzar a pasar de manera invisible (~90 % de probabilidad) |
| HTTP 403 → 503 | Actualizar comprobaciones de códigos de estado |
| Siempre visible → adaptable | Es posible que el widget no esté en HTML |
| Misma clave de sitio | El código de resolución CaptchaAI permanece igual |
| Misma checkout de qa_validation_cookie | El manejo de cookies sigue siendo el mismo |
Solución de problemas
| Síntoma | Causa | Solución |
|---|---|---|
| 503 sin widget visible | Managed Challenge superado de forma invisible | No se requiere acción: pasaste |
| 503 con "Comprobando tu navegador" | Managed escalado a challenge JS | Usa el método cloudflare_challenge |
| 403 con CAPTCHA visible | Interactive Challenge (heredado) | Usa el método turnstile |
| 403 sin challenge | Bloqueo WAF, no es un challenge | Cambia de IP o patrón de solicitud |
| El tipo de challenge cambia aleatoriamente | Managed Challenge adaptándose a las señales | Maneja tanto Turnstile como challenge JS |
| qa_validation_cookie de un tipo rechazada por otro | Flujos de challenge diferentes, mismo dominio | Resuelve el challenge que se presenta |
Preguntas frecuentes
¿Debo probar siempre primero el Desafío Gestionado?
Sí. La mayoría de los sitios utilizan Managed Challenge ahora. Comience con el método turnstile y recurra a cloudflare_challenge si la página muestra un desafío de JavaScript (503 con "Comprobando su navegador").
¿Puede un sitio utilizar ambos tipos en páginas diferentes?
Sí, pero es poco común. Cada regla WAF puede tener una acción diferente. Una regla podría usar Desafío administrado para /login y Desafío interactivo para /api/.
¿Managed Challenge todavía necesita una cookie qa_validation_cookie?
Sí. Ambos tipos de desafío producen la misma cookie qa_validation_cookie. El manejo de cookies es idéntico independientemente del tipo de desafío.
¿Qué pasa si Managed Challenge me pasa de manera invisible?
Si Managed Challenge decide que su solicitud es de bajo riesgo, la pasa sin un desafío visible. Su respuesta será un 200 normal con el contenido de la página. En este caso no es necesaria ninguna solución CaptchaAI.
¿El Desafío Interactivo está en desuso?
Cloudflare no lo ha desaprobado oficialmente, pero recomiendan Managed Challenge para todas las reglas nuevas. El desafío interactivo sigue siendo por compatibilidad con versiones anteriores. Los sitios pueden migrar en cualquier momento.
Resumen
Cloudflare Managed Challenge selecciona de forma adaptativa la dificultad del challenge por visitante (desde pase invisible hasta challenge JS completo), mientras que Interactive Challenge siempre presenta un CAPTCHA visible. Ambos producen la misma cookie qa_validation_cookie y se resuelven con CaptchaAI: usa turnstile para la mayoría de los challenges y cloudflare_challenge para las páginas de JavaScript challenge. Managed Challenge es el valor predeterminado moderno; Interactive Challenge es una opción heredada.
Artículos relacionados
- Cloudflare Browser Integrity Check vs CAPTCHA
- Cloudflare Challenge vs Turnstile: cómo detectar