Cómo funciona la puntuación de reCAPTCHA v3: el motor invisible de riesgo
Si has integrado reCAPTCHA v3 en un formulario o endpoint de API, sabes que no hay un desafío visual. En su lugar, grecaptcha.execute() devuelve un token opaco que tu backend envía a siteverify, y Google responde con un score continuo de 0.0 a 1.0 que representa la probabilidad de que la interacción sea humana. Comprender cómo funciona la puntuación de reCAPTCHA v3 es el primer paso para que los equipos de QA, automatización e investigación de anti-bot construyan flujos que obtengan un recaptcha v3 score aceptable sin recurrir a técnicas de evasión que violan términos de servicio.
Este artículo está orientado a ingenieros de QA e investigadores de anti-bot que necesitan automatizar accesos autorizados: pruebas de accesibilidad, QA de flujos de registro, o auditorías de seguridad con permiso explícito del propietario del sitio. No es una guía para eludir protecciones con fines fraudulentos.
El modelo de puntuación: once buckets y umbrales típicos
Google agrupa internamente el score en once buckets: 0.0, 0.1, 0.2, …, 0.9, 1.0. Cada bucket refleja un nivel de riesgo. La documentación oficial de Google Cloud recomienda que cada sitio defina sus propios umbrales, pero los patrones más comunes en 2026 son:
- Score < 0.3: bloquear o requerir verificación adicional (recaptcha score 0.3 es el punto de corte más frecuente para acciones sensibles como login o pago).
- Score 0.3–0.6: presentar un desafío secundario (v2 checkbox, email de verificación, MFA).
- Score > 0.6: permitir la acción sin fricción.
El score no es una decisión binaria. Es una entrada que tu backend debe combinar con contexto propio (velocidad de solicitudes, historial del usuario, volumen por IP) antes de actuar. Esto significa que un recaptcha v3 bypass no consiste en "engañar" al widget, sino en generar una señal de interacción que el motor clasifique como de bajo riesgo.
Por qué existe este problema: el contexto técnico
reCAPTCHA v3 fue diseñado para eliminar la fricción del captcha visual y, al mismo tiempo, mejorar la precisión de detección. El motor fusiona docenas de señales en un único modelo de machine learning que se ejecuta en los servidores de Google, no en el navegador del usuario. Esto crea una asimetría: el sitio solo ve el score final, pero no puede inspeccionar las señales individuales que lo produjeron.
Para los equipos de automatización, esto es un problema real. Un script que rellena un formulario en 200 ms con coordenadas de ratón perfectas y sin eventos de teclado reales puede parecer "eficiente" a nivel de código, pero para el motor de Google es estadísticamente anómalo. Los humanos no hacen clic en el centro exacto de un botón cada vez; no escriben a 600 caracteres por minuto sin pausas; no cargan una página y envían el formulario en menos de 500 ms.
Las señales que Google fusiona
Según la documentación pública de Google y análisis de la comunidad de seguridad, el motor de reCAPTCHA v3 combina al menos estas categorías de señales:
| Categoría de señal | Ejemplos concretos | Peso aproximado |
|---|---|---|
| Telemetría de interacción | Timing de mouse, scroll, keystrokes; trayectorias del cursor; pausas entre campos | Alto |
| Grafo de cookies de Google | Historial de navegación en propiedades de Google; antigüedad de la cuenta | Alto |
| Características del navegador | User-Agent, canvas fingerprint, WebGL renderer, orden de cipher suites TLS (JA3/JA4), APIs disponibles | Medio-alto |
| Reputación de IP | ASN, tipo de IP (residencial vs datacenter), historial de abuso, geolocalización | Alto |
| Patrones de sesión | Tiempo en página, número de acciones por sesión, secuencia de navegación | Medio |
El fingerprint TLS es especialmente relevante para quienes usan librerías HTTP en lugar de un navegador real. Un cliente Python con requests produce un handshake TLS con un orden de cipher suites (JA3) que no coincide con ningún navegador real. Google puede detectar esta discrepancia sin necesidad de ejecutar JavaScript. Si quieres profundizar en cómo funciona la huella TLS, consulta la especificación TLS 1.3 del IETF y los análisis de fingerprinting de MDN sobre User-Agent.
Por qué las IPs de datacenter colapsan el score
Independientemente de cuán perfecta sea tu simulación de comportamiento humano, si la solicitud proviene de una IP de datacenter, el componente de reputación de IP arrastrará el score hacia abajo. Google mantiene un grafo de reputación que clasifica IPs por tipo:
- Residencial: asignadas por ISPs a hogares. Alta confianza por defecto.
- Móvil: asignadas por operadores celulares. Alta confianza, especialmente útil para flujos de app.
- Datacenter: ASN de AWS, GCP, Azure, DigitalOcean, OVH, Hetzner. Reputación baja por defecto; históricamente asociadas con bots.
Una IP de datacenter con un ASN conocido puede recibir un score base de 0.1–0.2 antes de que se evalúe cualquier otra señal. Esto significa que incluso un navegador real operado manualmente desde una VM en AWS puede recibir un recaptcha v3 score de 0.2 o 0.3. Por eso, para automatización legítima que necesita cruzar reCAPTCHA v3, los proxies residenciales son un requisito técnico, no un lujo.
Los proxies residenciales enrutan tu tráfico a través de IPs asignadas a hogares por ISPs legítimos. Cuando Google consulta la reputación de esa IP, ve un ASN residencial con historial de tráfico humano normal, lo que establece un score base mucho más favorable. Puedes consultar la cobertura de ubicaciones de ProxyHat en /es/locations.
Cómo funciona la verificación del token en el servidor
Cuando grecaptcha.execute(siteKey, {action: 'login'}) se ejecuta en el navegador, devuelve un token JWT que dura aproximadamente 120 segundos. Tu frontend envía este token al backend junto con los datos del formulario. El backend entonces llama a:
POST https://www.google.com/recaptcha/api/siteverify
secret=YOUR_SECRET_KEY
response=TOKEN_DEL_CLIENTE
remoteip=IP_DEL_USUARIO (opcional)
Google responde con un JSON que incluye:
success: booleano, true si el token es válido y no ha expirado.score: float de 0.0 a 1.0.action: string con la acción que se ejecutó en el cliente.hostname: dominio desde el que se ejecutó el widget.error-codes: array de códigos de error si algo falló.
Dos validaciones críticas que muchos equipos olvidan:
- El action debe coincidir: si el frontend ejecutó
{action: 'login'}pero tu backend esperaba'submit_form', debes rechazar el token. Un atacante que captura un token válido para una acción de bajo riesgo (como'page_view') no debe poder reutilizarlo para una acción de alto riesgo (como'transfer_money'). - El hostname debe coincidir: si el token se generó en
example.compero tu backend recibe la solicitud desdeevil.com, recházala. Google incluye el hostname en la respuesta para que puedas verificarlo.
Estas dos comprobaciones son responsabilidad del backend, no de Google. Google te da los datos; tú decides. Si no validas action y hostname, estás expuesto a ataques de reemplazo de token.
Implementación práctica con ProxyHat y un navegador real
Para que la automatización legítima obtenga un recaptcha v3 score por encima del umbral, necesitas tres componentes trabajando juntos:
- IP residencial vía ProxyHat para que el componente de reputación de IP no penalice el score.
- Navegador real (no
requestsnicurl) para que el fingerprint del navegador y la telemetría de interacción sean auténticos. - Comportamiento humano simulado: pausas realistas, movimiento de ratón con curvas bézier, tiempo de lectura de página.
Ejemplo en Python con Playwright y ProxyHat
Este ejemplo asume que tienes una clave de sitio de reCAPTCHA v3 de prueba (las claves de test de Google usan sitekey=6LcR_REUAAAAALMxZkgJzqkqBvFEPq9 y siempre devuelven score 0.9, pero para producción necesitas tu propio sitio de prueba).
from playwright.sync_api import sync_playwright
import time
import random
PROXY = "http://user-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080"
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False, # headless=True puede reducir el score
proxy={"server": PROXY}
)
context = browser.new_context(
viewport={"width": 1920, "height": 1080},
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://tu-sitio-de-prueba.com/login")
# Simular lectura humana: 2-4 segundos de pausa
time.sleep(random.uniform(2.0, 4.0))
# Mover el ratón con trayectoria curva antes de interactuar
page.mouse.move(500, 300, steps=20)
time.sleep(random.uniform(0.3, 0.8))
page.mouse.move(600, 400, steps=15)
# Escribir el campo de email con pausas realistas
page.click("#email")
for char in "usuario@example.com":
page.type("#email", char, delay=random.randint(50, 150))
time.sleep(random.uniform(0.5, 1.5))
# Ejecutar reCAPTCHA v3 para la acción 'login'
token = page.evaluate("""
() => new Promise((resolve) => {
grecaptcha.execute('SITE_KEY', {action: 'login'})
.then(token => resolve(token));
})
""")
# Enviar el token al backend para siteverify
print(f"Token: {token[:50]}...")
# El backend debe llamar a siteverify y verificar action == 'login'
# y hostname == 'tu-sitio-de-prueba.com'
browser.close()
Notas clave sobre este enfoque:
headless=Falsees importante: los navegadores headless tienen diferencias detectables en el fingerprint (por ejemplo,navigator.webdriver, ausencia de GPU real) que pueden reducir el score en 0.1–0.3 puntos.- El proxy residencial de ProxyHat usa el formato
user-country-US:PASSWORD@gate.proxyhat.com:8080. Puedes cambiarUSpor cualquier país soportado; consulta /es/locations para la lista completa. - Los
delayaleatorios enpage.type()simulan la cadencia humana. Escribir a velocidad constante es una señal de bot. - El movimiento del ratón con
steps=20genera una trayectoria con interpolación, no un salto instantáneo.
Configuración del proxy en línea de comandos
Si necesitas probar manualmente con curl antes de integrar el proxy en tu script:
curl -x http://user-country-US:PASSWORD@gate.proxyhat.com:8080 \
https://httpbin.org/ip
Para SOCKS5, usa el puerto 1080:
curl -x socks5://user-country-US:PASSWORD@gate.proxyhat.com:1080 \
https://httpbin.org/ip
Consulta la documentación oficial de ProxyHat para detalles sobre sesiones sticky, rotación por petición y geo-targeting a nivel de ciudad.
Errores comunes y casos límite
Error 1: Usar requests o curl en lugar de un navegador
Si ejecutas grecaptcha.execute() en un entorno sin un DOM real (por ejemplo, inyectando el script en Node.js sin un navegador), el widget no puede recolectar telemetría de interacción. El score resultante será típicamente 0.1–0.2 porque el motor detecta la ausencia de señales de interacción.
Error 2: Reutilizar tokens
Los tokens de reCAPTCHA v3 son de un solo uso y expiran en ~120 segundos. Si intentas reutilizar un token, siteverify devuelve success: false con error-codes: ["timeout-or-duplicate"]. Cada acción requiere un token fresco.
Error 3: No validar el action en el backend
Si tu backend solo comprueba success == true y score >= 0.5, pero no verifica que action coincida con la acción esperada, un atacante puede capturar un token de una acción de bajo riesgo y reutilizarlo para una acción de alto riesgo. Este es uno de los errores más comunes y peligrosos.
Error 4: Confiar solo en el score sin contexto
Un score de 0.7 en una acción de 'login' desde una IP nueva en un país diferente al habitual del usuario puede ser sospechoso aunque supere el umbral. Combina el score con tu propia telemetría: ratio de solicitudes por IP, frecuencia de login por cuenta, coincidencia geográfica.
Error 5: Headless sin mitigaciones
Playwright y Puppeteer en modo headless exponen señales como navigator.webdriver === true, ausencia de plugins, y un User-Agent que incluye "HeadlessChrome". Estas señales pueden reducir el score en 0.1–0.3 puntos. Usa herramientas como playwright-stealth o ejecuta en modo headless=False con un display virtual (Xvfb) en entornos de servidor.
Configuración específica de ProxyHat
ProxyHat ofrece tres tipos de proxies. Para reCAPTCHA v3, la elección correcta es casi siempre residencial:
| Tipo de proxy | Reputación de IP | Adecuado para reCAPTCHA v3 | Coste relativo |
|---|---|---|---|
| Residencial | Alta (ASN de ISP) | Sí — recomendado | Medio-alto |
| Móvil | Muy alta (ASN de operador) | Sí — ideal para flujos de app | Alto |
| Datacenter | Baja (ASN de cloud) | No — score colapsará | Bajo |
Para configurar la rotación y las sesiones:
- Rotación por petición (default): cada solicitud usa una IP diferente. Útil para scraping distribuido, pero puede generar scores inconsistentes en flujos de múltiples pasos.
- Sesión sticky: usa
user-session-abc123en el username para mantener la misma IP durante toda la sesión. Esto es crítico para reCAPTCHA v3, porque el motor evalúa la consistencia de la sesión. Si la IP cambia a mitad de un flujo de login, el score baja. - Geo-targeting por país:
user-country-USasegura que la IP esté en EE. UU., lo que es importante si el sitio que pruebas espera tráfico de una región específica.
Ejemplo de sesión sticky con geo-targeting:
http://user-country-US-session-qa-login-001:PASSWORD@gate.proxyhat.com:8080
Consulta los planes de precios de ProxyHat para elegir el volumen de tráfico residencial adecuado a tu caso de uso. Para casos de uso de scraping web a mayor escala, visita /es/use-cases/web-scraping; para tracking de SERP, /es/use-cases/serp-tracking.
Dónde es apropiado usar esta técnica
Este enfoque es legítimo en estos contextos:
- QA automatizado de tus propios sitios o sitios de clientes con autorización por escrito.
- Pruebas de accesibilidad: verificar que usuarios con lectores de pantalla pueden completar flujos protegidos por reCAPTCHA v3.
- Auditorías de seguridad autorizadas: pentesting con scope firmado que incluye evaluación de controles anti-bot.
- Investigación de anti-bot: análisis académico o de la industria con consentimiento del objetivo.
No es legítimo para:
- Creación masiva de cuentas en sitios de terceros.
- Compra automatizada de productos limitados (sneaker bots, ticketing) violando los términos de servicio del sitio.
- Fraude publicitario, click fraud, o manipulación de métricas.
- Acceso no autorizado a sistemas protegidos (esto puede constituir una violación del CFAA en EE. UU. y de normativas equivalentes en otras jurisdicciones).
Además, si tu automatización procesa datos personales de usuarios de la UE, debes cumplir con el GDPR: base legal para el tratamiento, minimización de datos, y respetar las solicitudes de eliminación. La automatización no exime de las obligaciones de privacidad; al contrario, el procesamiento a escala amplifica el riesgo regulatorio.
Puntos clave (Key Takeaways)
reCAPTCHA v3 devuelve un score continuo de 0.0 a 1.0 que tu backend debe combinar con contexto propio. El umbral típico es bloquear <0.3, desafiar 0.3–0.6, permitir >0.6.
- El score fusiona telemetría de interacción, grafo de cookies de Google, fingerprint del navegador (incluyendo JA3/JA4 TLS) y reputación de IP.
- Las IPs de datacenter colapsan el score a 0.1–0.2 independientemente del comportamiento. Los proxies residenciales son un requisito técnico, no opcional.
- El backend debe validar
actionyhostnameen cada llamada asiteverify. Sin estas validaciones, el sistema es vulnerable a ataques de reemplazo de token. - Usa un navegador real (Playwright/Puppeteer en modo no-headless o con stealth), proxy residencial con sesión sticky, y simulación de comportamiento humano para obtener scores consistentemente por encima de 0.5.
- Este enfoque es legítimo solo para QA autorizado, pruebas de accesibilidad e investigación con consentimiento. El uso no autorizado puede violar el CFAA y el GDPR.
Si necesitas proxies residenciales con sesiones sticky y geo-targeting para tu próxima batería de pruebas, explora los planes de ProxyHat y configura tu primera sesión en minutos.






