Internos de Cloudflare Turnstile: cómo detecta automatización y cómo pasarlo de forma limpia en 2026

Análisis técnico de los internos de Cloudflare Turnstile, la cookie cf_clearance, el trust score basado en JA4 y por qué los proxies residenciales sticky son imprescindibles para automatización legítima.

Cloudflare Turnstile Internals: Passing the Trust Score
En este artículo

Los internos de Cloudflare Turnstile determinan si una petición HTTP llega de un navegador real o de un script de automatización. En 2026, Turnstile ya no muestra necesariamente un CAPTCHA visual: ejecuta un desafío gestionado invisible que combina JavaScript, prueba de trabajo y señales de red para calcular una puntuación de confianza. Si esa puntuación cae por debajo del umbral del sitio, la petición se bloquea o se desafía. Para ingenieros de scraping e investigadores de seguridad, entender estos internos no es opcional: es la diferencia entre una recolección de datos estable al 99% y una tarifa de bloqueos del 80%.

Aviso legal. Esta guía cubre acceso a datos públicos y automatización autorizada —por ejemplo, investigación de seguridad con consentimiento del propietario, monitoreo de precios en sitios propios o recolección de datos públicos cumpliendo los Términos de Servicio. Eludir controles de acceso para credenciales ajenas, scraping de datos protegidos por login sin autorización o violar la CFAA, el RGPD o los ToS de un sitio puede ser ilegal. Consulta a tu asesor legal antes de implementar nada en producción.

Cloudflare Turnstile sustituyó al antiguo CAPTCHA hCaptcha/reCAPTCHA por un flujo de desafío gestionado que se ejecuta sin interacción del usuario en la mayoría de los casos. Cuando el borde de Cloudflare detecta una petición sospechosa, inyecta un widget JavaScript que carga desde challenges.cloudflare.com. Ese script realiza tres tareas principales:

  • Prueba de trabajo (PoW). El servidor envía una semilla aleatoria y el navegador debe encontrar un nonce tal que SHA-256(seed || nonce) cumpla una dificultad objetivo. La dificultad escala con la sospecha: una petición neutra puede requerir unos 50.000 hashes, mientras que una petición de alta sospecha puede exigir más de 1.000.000. Un navegador real completa esto en 200–800 ms; un script sin WebAssembly optimizado tarda varios segundos, lo cual ya es una señal.
  • Sondeos de API del navegador. El script interroga propiedades como navigator.webdriver, navigator.plugins, window.chrome, Notification.permission, la lista de fuentes instaladas y los valores devueltos por WebGLRenderingContext.getParameter. Un headless Chrome sin parchear devuelve navigator.webdriver === true y una lista de plugins vacía —ambos marcadores rojos inmediatos.
  • Recolección de huella de canvas, WebGL y audio. Turnstile renderiza escenas WebGL y dibuja texto en un canvas fuera de pantalla, luego hashea el resultado. El hash resultante depende del driver gráfico, la versión del navegador y el sistema operativo. Un headless Chrome en un servidor Linux sin GPU produce un hash de canvas distinto al de un Chrome real en Windows, lo que permite detectar entornos automatizados.

Si el navegador supera el desafío, Cloudflare emite la cookie cf_clearance. Esta cookie es un token firmado criptográficamente que autoriza peticiones posteriores durante un período configurable (típicamente 30 minutos a 24 horas, según la configuración del sitio). Lo crítico: cf_clearance está vinculada estrictamente a la combinación de IP + User-Agent que se usó al resolver el desafío. Si cualquiera de los dos cambia, la cookie se rechaza y el cliente debe resolver un nuevo desafío.

Los cuatro pilares del trust score de Cloudflare Bot Management

Turnstile es solo la capa visible. Detrás, Cloudflare Bot Management calcula un trust score continuo a partir de cuatro familias de señales. Una sola señal anómala basta para desafiar; dos señales anómalas casi siempre bloquean.

1. Huella TLS JA4

JA4 es el sucesor de JA3 y aporta una diferencia clave: ordena las extensiones TLS antes de hashearlas. En JA3, el orden de extensiones dependía de la implementación y era inestable; JA4 normaliza ese orden, lo que produce un hash estable y reproducible por cliente. Cada navegador tiene un JA4 característico:

  • Chrome 120+ en Windows: t13d1516h2_8daaf6152771_b0da82dd1658
  • Firefox 121 en Linux: t13d1718h2_5b57614c22b0_5e67e5b6b4d8
  • Python requests con OpenSSL 3.0: t13d1714h2_5b57614c22b0_8d872a4f7701

El campo 1516 indica 15 cifrados y 16 extensiones en orden ascendente; el segundo grupo es el hash de cifrados y extensiones; el tercero es el hash de extensiones de firma. Si una petición declara User-Agent: Mozilla/5.0 ... Chrome/120 pero su JA4 corresponde a OpenSSL, Cloudflare lo detecta en milisegundos. No importa cuán perfecto sea tu header: la huella TLS te delata antes de que se lea el primer byte HTTP.

2. Ajustes HTTP/2 (SETTINGS frame)

Cloudflare inspecciona el frame SETTINGS de HTTP/2, que cada cliente envía al inicio de la conexión. Los valores de HEADER_TABLE_SIZE, ENABLE_PUSH, MAX_CONCURRENT_STREAMS, INITIAL_WINDOW_SIZE y MAX_FRAME_SIZE forman una huella estable por implementación. Chrome envía HEADER_TABLE_SIZE=65536 y INITIAL_WINDOW_SIZE=4194304; curl envía valores distintos; Python httpx con h2 envía otros. Esta señal complementa a JA4: juntas, TLS + HTTP/2 identifican al cliente con una precisión cercana al 100%.

3. Huella del navegador (canvas, WebGL, audio)

El JavaScript de Turnstile genera un hash combinado de:

  • Canvas 2D: renderiza una escena con texto, gradientes y formas; el hash del pixel buffer depende de la implementación de Skia/Blink y del driver de fuente.
  • WebGL: consulta UNMASKED_VENDOR_WEBGL y UNMASKED_RENDERER_WEBGL. Un headless Chrome reporta Google Inc. (Google) y ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device)), mientras que un Chrome real en Windows reporta el proveedor de GPU real (Intel, NVIDIA, AMD).
  • AudioContext: genera un tono con un OscillatorNode y hashea la salida de AnalyserNode. El valor depende de la implementación de audio del SO.

Combinados, estos tres hashes forman un identificador de dispositivo casi único. Cloudflare mantiene una base de datos de hashes asociados a bots conocidos.

4. Reputación de IP

La cuarta señal es la reputación de la IP de salida. Cloudflare clasifica IPs en rangos: residencial, móvil, datacenter, VPN conocida, Tor. Una IP de datacenter (AWS, DigitalOcean, OVH) recibe una penalización base; una IP residencial legítima recibe un bonus. Esta señal es la que más peso tiene cuando las tres anteriores son ambiguas: si la huella TLS y HTTP/2 coinciden con Chrome pero la IP es 3.1.x.x de AWS, el score baja.

SeñalPeso aproximadoDetección de automatización
JA4 TLSAltoInconsistencia entre UA declarado y stack TLS real
HTTP/2 SETTINGSAltoFrame SETTINGS no coincide con navegador declarado
Huella de navegadorMedio-altoCanvas/WebGL de headless o entorno sin GPU
Reputación de IPMedioIP de datacenter o VPN conocida

Por qué una conexión que dice ser Chrome pero presenta un JA4 de Python es desafiada al instante

Este es el error más común entre principiantes. Un desarrollador copia el User-Agent de Chrome en su script de Python requests y asume que Cloudflare lo aceptará. No funciona. El flujo es así:

  1. Python abre una conexión TLS a example.com.
  2. El TLS ClientHello contiene los cifrados y extensiones de OpenSSL, no de BoringSSL (la librería que usa Chrome).
  3. Cloudflare calcula JA4 del ClientHello y obtiene t13d1714h2_... —un hash asociado a OpenSSL/Python.
  4. Cloudflare lee el header User-Agent y ve Chrome/120.
  5. El sistema detecta la inconsistencia JA4 ≠ UA y asigna un score bajo.
  6. La petición recibe un desafío 403 con el HTML de Turnstile, no la página objetivo.

Ningún proxy puede arreglar esto por sí solo. El proxy cambia la IP, pero la huella TLS sigue siendo la de Python. Para pasar de forma limpia, necesitas un cliente que produzca un JA4 coincidente con su User-Agent —es decir, un navegador real o una librería que replique exactamente el stack TLS de Chrome, como tls-client o curl con HTTP/2 y BoringSSL.

Por qué los proxies residenciales son imprescindibles para Turnstile

Incluso con un navegador real y un JA4 correcto, la reputación de IP sigue siendo una señal. Una IP de datacenter puede reducir tu score lo suficiente como para forzar un desafío en cada petición. Peor aún: cf_clearance está vinculada a la IP exacta con la que se resolvió el desafío. Si tu proxy rota IPs por petición (rotación per-request), la cookie se invalida en cada rotación y debes resolver un nuevo desafío constantemente —lo que agota recursos y aumenta la latencia.

La solución es una sesión residencial sticky: una IP residencial que se mantiene estable durante toda la sesión. Con esa IP, resuelves el desafío una vez, obtienes cf_clearance y reutilizas la cookie en peticiones posteriores mientras la IP no cambie. Esto reduce los desafíos de uno por petición a uno por sesión —una mejora de rendimiento enorme.

ProxyHat ofrece sesiones sticky mediante un flag en el nombre de usuario. La sintaxis es user-session-abc123:pass, donde abc123 es un identificador de sesión arbitrario. Mientras uses el mismo identificador, ProxyHat enruta tu tráfico por la misma IP residencial.

Implementación práctica: ProxyHat sticky residential + navegador real

El enfoque más robusto para automatización legítima es usar un navegador real (Playwright o Puppeteer con Chrome completo, no headless sin parchear) detrás de un proxy residencial sticky de ProxyHat. El navegador produce un JA4 correcto de forma nativa; el proxy residencial mejora la reputación de IP; la sesión sticky mantiene cf_clearance válida.

Paso 1: Configurar el proxy sticky en el navegador

Con Playwright en Python:

from playwright.sync_api import sync_playwright

proxy_url = "http://user-session-abc123:pass@gate.proxyhat.com:8080"

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=False,  # o headless con flags de stealth
        proxy={"server": proxy_url}
    )
    context = browser.new_context(
        user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                   "AppleWebKit/537.36 (KHTML, like Gecko) "
                   "Chrome/120.0.0.0 Safari/537.36"
    )
    page = context.new_page()
    page.goto("https://ejemplo-protegido.com")
    # Esperar a que Turnstile resuelva automáticamente
    page.wait_for_timeout(5000)
    # Extraer cf_clearance
    cookies = context.cookies()
    cf_clearance = next(
        (c["value"] for c in cookies if c["name"] == "cf_clearance"), None
    )
    print(f"cf_clearance: {cf_clearance}")

Paso 2: Reutilizar cf_clearance en peticiones posteriores

Una vez que tienes cf_clearance, puedes reutilizarla en peticiones HTTP directas —siempre que uses la misma IP y el mismo User-Agent:

import requests

proxy = "http://user-session-abc123:pass@gate.proxyhat.com:8080"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                 "AppleWebKit/537.36 (KHTML, like Gecko) "
                 "Chrome/120.0.0.0 Safari/537.36",
    "Cookie": f"cf_clearance={cf_clearance}"
}

resp = requests.get(
    "https://ejemplo-protegido.com/api/datos",
    proxies={"http": proxy, "https": proxy},
    headers=headers
)
print(resp.status_code)  # 200 si todo está bien

Sin embargo, aquí hay un problema: requests usa OpenSSL, no BoringSSL, así que su JA4 no coincide con Chrome. Cloudflare puede validar cf_clearance pero seguir detectando la inconsistencia TLS en peticiones sensibles. Para máxima fiabilidad, usa la documentación de ProxyHat junto con una librería como tls-client que replique el JA4 de Chrome, o continúa usando el navegador Playwright para todas las peticiones.

Paso 3: Ejemplo con curl y SOCKS5

Para pruebas rápidas, puedes usar curl con el proxy SOCKS5 de ProxyHat:

curl -x socks5://user-session-abc123:pass@gate.proxyhat.com:1080 \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \
  -H "Cookie: cf_clearance=TOKEN_AQUI" \
  https://ejemplo-protegido.com/api/datos

Curl con OpenSSL también produce un JA4 distinto a Chrome, así que esto sirve para validación de cf_clearance pero no para resolver un nuevo desafío sin navegador.

Errores comunes y casos límite

Error 1: Usar proxies datacenter para resolver Turnstile

Una IP de datacenter recibe un score base más bajo. Incluso con un navegador real, Turnstile puede exigir una prueba de trabajo más larga o un segundo desafío interactivo. Solución: usa proxies residenciales como los de las ubicaciones de ProxyHat.

Error 2: Rotar IP después de obtener cf_clearance

Si cambias de sesión sticky o usas rotación per-request, cf_clearance se invalida inmediatamente. Debes mantener el mismo session-abc123 durante toda la vida útil de la cookie.

Error 3: Cambiar el User-Agent entre la resolución y el reuso

Cloudflare vincula cf_clearance a IP + User-Agent. Si resuelves el desafío con Chrome 120 y luego reusas la cookie con un UA de Firefox, la cookie se rechaza. Mantén el mismo UA exacto en todas las peticiones.

Error 4: Headless Chrome sin stealth

Un headless Chrome sin parchear expone navigator.webdriver === true, no tiene plugins y reporta una GPU SwiftShader. Turnstile detecta estos marcadores en menos de 200 ms. Solución: usa playwright-stealth o lanza Chrome con --headless=new y flags de stealth, o mejor aún, usa Chrome en modo headed con un display virtual (Xvfb).

Error 5: Conexiones concurrentes desde la misma IP sticky

Si abres 50 peticiones concurrentes desde la misma IP residencial, Cloudflare puede marcarlo como comportamiento anómalo. Limita la concurrencia a 5–10 por IP sticky, o usa múltiples sesiones sticky con identificadores distintos para distribuir la carga.

Configuración específica de ProxyHat

ProxyHat soporta tres tipos de proxies: residenciales, móviles y datacenter. Para Turnstile, los residenciales son la opción por defecto; los móviles ofrecen reputación aún mejor pero a mayor coste; los datacenter no se recomiendan para resolver desafíos.

Formatos de conexión:

  • HTTP: http://user-session-abc123:pass@gate.proxyhat.com:8080
  • SOCKS5: socks5://user-session-abc123:pass@gate.proxyhat.com:1080
  • Geo-targeting por país: http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080
  • Geo-targeting por ciudad: http://user-country-DE-city-berlin-session-abc123:pass@gate.proxyhat.com:8080

Para automatización de scraping a escala, revisa la página de precios y los casos de uso de web scraping y SERP tracking para entender qué plan se ajusta a tu volumen.

Cuándo es apropiado este enfoque

Eludir Turnstile es legítimo en estos escenarios:

  • Investigación de seguridad autorizada. Pentesting con permiso escrito del propietario del sitio.
  • Acceso a datos públicos. Páginas visibles sin login, siempre que el sitio no prohíba el scraping en sus ToS.
  • Monitoreo de precios en sitios propios o de socios. Cuando tienes un acuerdo comercial.
  • QA automatizado. Pruebas de tu propia infraestructura detrás de Cloudflare.

No es apropiado para:

  • Acceso a cuentas de terceros sin autorización.
  • Scraping de datos protegidos por login sin consentimiento.
  • Elusión de rate limits para abuso de APIs.
  • Cualquier actividad que viole la CFAA o el RGPD.

Cloudflare ha mejorado significativamente su detección en los últimos dos años. Según el blog de Cloudflare, Bot Management bloquea más de 150.000 millones de peticiones de bots al día. La consistencia de tu stack —TLS, HTTP/2, navegador, IP— es lo único que determina si pasas de forma limpia o si eres desafiado en cada petición.

Puntos clave

  • Turnstile es invisible. El desafío gestionado combina prueba de trabajo, sondeos de API del navegador y huella de canvas/WebGL. No necesitas resolver un CAPTCHA visual para que te bloqueen.
  • cf_clearance está vinculada a IP + User-Agent. Cambiar cualquiera de los dos invalida la cookie. Usa sesiones sticky residenciales para mantenerla válida.
  • JA4 es la señal más fiable. Ordena extensiones TLS antes de hashear, produciendo un hash estable por navegador. Python no puede fingir ser Chrome a nivel TLS sin librerías especializadas.
  • La reputación de IP importa. Una IP de datacenter baja tu score base; una IP residencial lo sube. ProxyHat residencial con sesión sticky es la combinación óptima.
  • La consistencia lo es todo. TLS + HTTP/2 + navegador + IP deben coincidir. Una sola inconsistencia basta para un desafío.
  • Usa esto solo para acceso legítimo. Datos públicos, investigación autorizada, QA propio. No para abuso de credenciales ni violación de ToS.

Preguntas frecuentes

¿Qué son los internos de Cloudflare Turnstile?

Los internos de Cloudflare Turnstile son el conjunto de mecanismos invisibles que el sistema usa para distinguir navegadores reales de bots: un desafío gestionado en JavaScript que incluye prueba de trabajo, sondeos de APIs del navegador (navigator.webdriver, plugins, WebGL), huella de canvas y audio, y la emisión de la cookie cf_clearance vinculada a IP y User-Agent. No muestra un CAPTCHA visual en la mayoría de los casos; calcula una puntuación de confianza y decide si la petición pasa, se desafía o se bloquea.

¿Por qué importan los internos de Cloudflare Turnstile para usuarios de proxies?

Porque cf_clearance está vinculada estrictamente a la IP y al User-Agent con los que se resolvió el desafío. Si un proxy rota IPs por petición, la cookie se invalida en cada rotación y el cliente debe resolver un nuevo desafío constantemente, aumentando latencia y riesgo de bloqueo. Los proxies residenciales con sesiones sticky mantienen la misma IP durante toda la sesión, permitiendo reutilizar cf_clearance y reducir los desafíos de uno por petición a uno por sesión.

¿Qué tipo de proxy funciona mejor para los internos de Cloudflare Turnstile?

Los proxies residenciales con sesiones sticky son la mejor opción. Ofrecen mejor reputación de IP que los datacenter (que reciben penalización base en el trust score) y mantienen una IP estable para que cf_clearance permanezca válida. Los proxies móviles ofrecen reputación aún superior pero a mayor coste. Los datacenter no se recomiendan para resolver desafíos de Turnstile porque Cloudflare los penaliza en el score de bot management.

¿Cómo evitar bloqueos al implementar los internos de Cloudflare Turnstile?

Para evitar bloqueos, usa un navegador real (Playwright o Puppeteer con Chrome completo y flags de stealth) detrás de un proxy residencial sticky. El navegador produce un JA4 TLS nativo correcto, el proxy residencial mejora la reputación de IP, y la sesión sticky mantiene cf_clearance válida. Mantén el mismo User-Agent en todas las peticiones, limita la concurrencia a 5–10 por IP sticky, y nunca uses proxies datacenter para resolver el desafío inicial. Evita headless Chrome sin parchear, que expone navigator.webdriver=true.

¿Qué es JA4 y por qué detecta a Python aunque el User-Agent diga Chrome?

JA4 es una huella TLS que ordena las extensiones del ClientHello antes de hashearlas, produciendo un hash estable y reproducible por navegador. Chrome usa BoringSSL y produce un JA4 distinto a Python, que usa OpenSSL. Cuando una petición declara User-Agent de Chrome pero su JA4 corresponde a OpenSSL, Cloudflare detecta la inconsistencia en milisegundos y desafía la petición. Ningún proxy puede arreglar esto: necesitas un navegador real o una librería como tls-client que replique el stack TLS de Chrome.

¿Listo para empezar?

Proxies residenciales, ISP y móviles en más de 148 países. Crea una cuenta gratis.

Crear cuenta gratis
← Volver al Blog