Cómo bloqueamos el 92% de bots en una tienda PS8 con Turnstile

📖 Serie Parte 3 de 3
Cloudflare Turnstile en PrestaShop 8

En septiembre de 2025 teníamos un problema concreto: 850 registros de cuenta nuevos al mes, de los cuales el 94% eran bots. Formularios de contacto con mensajes de spam automatizados. Reseñas de producto con URLs de phishing. Nada nuevo para cualquier tienda con tráfico real. Lo que sí era nuevo era cuánto habían mejorado los bots.

Este es el registro exacto de lo que hicimos, con los números antes y después.

El estado previo: reCAPTCHA v2 + honeypot, y no bastaba

Llevábamos dos años con reCAPTCHA v2 en el formulario de contacto y con un campo honeypot en el formulario de registro. A finales de 2024 el volumen de spam empezó a crecer de forma sostenida. En julio de 2025 documentamos 850 registros bot en un solo mes.

Revisamos los logs. El 60% de los bots resolvía el reCAPTCHA v2 sin problema. Los servicios de resolución de CAPTCHAs que operan con granjas de trabajo humano cobran 0,001€ por imagen. A ese precio, un actor que quiera hacer spam masivo en una tienda puede resolver 10.000 CAPTCHAs por 10€.

El honeypot seguía funcionando para los bots más simples, pero los más sofisticados lo ignoraban: rellenan solo los campos visibles y detectan los campos ocultos por CSS.

Intentamos activar reCAPTCHA v3 y establecer un umbral de puntuación de 0.7. Resultado: 18% de falsos positivos en clientes reales desde IPs de operadoras móviles compartidas (varios clientes usan la misma IP saliente de la operadora). Demasiado para dejarlo en producción.

Por qué elegimos Turnstile

El criterio principal no fue técnico sino legal. Nuestro equipo jurídico ya había señalado el uso de reCAPTCHA como un punto a corregir en el registro de actividades de tratamiento. Con Schrems II y las directrices de las autoridades de protección de datos europeas, seguir usando reCAPTCHA requería documentar una base legal sólida para la transferencia a EEUU.

Turnstile resolvía ambos problemas: sin tracking cruzado declarado, con procesamiento en edge europeo y, según las pruebas previas de otros proyectos, con tasas de falso positivo muy bajas incluso en IPs de operadoras compartidas.

El factor económico era irrelevante: el free tier de 1M challenges mensuales cubre sin problema nuestra escala.

El setup: 15 minutos de configuración real

Creamos el sitio en el dashboard de Cloudflare, obtuvimos las dos claves (Site Key y Secret Key) e instalamos el módulo en el Back Office de PrestaShop. Tiempo total desde cero: 14 minutos.

Configuración elegida:

  • Widget mode: Managed — Cloudflare decide si presentar challenge o no según sus señales
  • Action on fail: Block — rechazar la petición si el token no es válido
  • API timeout: 4 segundos — si la API de Cloudflare no responde en 4s, dejamos pasar la petición (fail open) para no bloquear clientes legítimos por un problema de infraestructura
  • Log enabled: Sí — registrar todos los intentos con IP, user-agent y resultado
  • Restriction de hostname: activada en el dashboard de Cloudflare — el token solo es válido si viene de nuestro dominio

Una cosa que no estaba en la documentación original y descubrimos en los logs: algunos bots intentan reutilizar tokens obtenidos en otros sitios que también usan Turnstile. El error hostname-mismatch los bloquea automáticamente. En el primer mes vimos 2.847 intentos de este tipo.

Los resultados primer mes

Datos del periodo octubre vs septiembre 2025:

Métrica Sep 2025 (pre-Turnstile) Oct 2025 (post-Turnstile) Variación
Registros nuevos totales 905 118 -87%
Registros bot confirmados 850 70 -92%
Registros clientes reales 55 48 -13% (estacional)
Falsos positivos 0* 1
Mensajes contacto spam 312 9 -97%
Reseñas spam 47 2 -96%

*El reCAPTCHA v3 generaba ~10% de falsos positivos en nuestra configuración anterior con umbral 0.7. Con v2 no medíamos falsos positivos porque el widget era visible y los clientes podían intentarlo de nuevo.

El único falso positivo del mes fue un cliente con un entorno de navegación muy restrictivo (JavaScript parcialmente bloqueado por extensiones de privacidad). Al recargar la página con las extensiones desactivadas, el formulario funcionó sin problema.

Análisis de los logs: qué tipos de bots bloqueamos

El módulo registra los error-codes de Cloudflare por cada verificación fallida. Distribución del primer mes:

  • invalid-input-response (token malformado o sin token): 38% de los intentos bloqueados. Bots que ni siquiera intentan obtener un token válido.
  • hostname-mismatch (token de otro dominio): 31%. Reutilización de tokens entre sitios.
  • timeout-or-duplicate (token caducado o ya usado): 21%. Bots que resuelven el challenge pero esperan demasiado antes de enviar, o que intentan reutilizar el mismo token varias veces.
  • invalid-input-response (challenge fallido): 10%. Bots que intentan resolver el challenge pero no pasan las pruebas de Cloudflare.

El 92% de reducción en registros bot no significa que el 8% restante sea tráfico legítimo que está pasando. Significa que el 8% de los bots del mes anterior sigue encontrando la forma de pasar el challenge: mayoritariamente bots que operan en navegadores reales con IPs residenciales, que son indistinguibles de usuarios humanos para cualquier sistema de verificación.

Para ese 8%, la única solución es detección de comportamiento post-registro (patrones de uso anómalos, verificación de email activa, análisis de actividad en las primeras 24h). Turnstile no es la última línea de defensa, pero elimina el ruido que hace imposible trabajar en ese nivel de detalle.

La mejora colateral que no esperábamos

Al retirar el script de reCAPTCHA del head de la página de contacto, el tiempo de carga de esa página bajó 110ms en median (medido con WebPageTest desde Frankfurt, conexión 4G simulada). reCAPTCHA carga tres scripts de dominios distintos de Google con un total de ~180KB. El script de Turnstile son 45KB desde un CDN de Cloudflare.

No es el factor principal para elegir Turnstile, pero es un beneficio real.

Configuración que recomendamos para la mayoría de tiendas

Después de tres meses con el sistema en producción, esta es la configuración que dejaríamos en una tienda nueva:

  • Modo managed (no invisible) — el badge de Cloudflare visible en el formulario actúa como señal disuasoria para bots simples
  • Action on fail: block — salvo en tiendas con audiencias técnicas donde los falsos positivos son una preocupación real
  • API timeout: 5 segundos — el 99.9% de las verificaciones de Cloudflare responden en menos de 500ms; un timeout de 5s cubre cualquier anomalía puntual
  • Logging: activado siempre — los datos de los primeros meses son valiosos para entender el perfil de bots que ataca tu tienda específicamente
  • Restricción de hostname en Cloudflare: siempre — elimina el 31% de intentos de reutilización de tokens sin coste adicional

Si tienes una situación similar en tu PrestaShop 8 — spam en registro, formulario de contacto como vector de entrada, reseñas automatizadas — el módulo Zeyvro Turnstile implementa todo lo que describimos en este artículo con una interfaz de configuración en el BO y logging completo. Abre un ticket y te ayudamos con el setup específico de tu tienda.

Si aún no tienes claro si Turnstile es lo que necesitas, empieza por el artículo informativo sobre reCAPTCHA vs Turnstile y vuelve aquí cuando tengas el contexto completo.

Descarga el módulo

Zeyvro Turnstile es gratis y open source bajo licencia MIT. Descarga directa, instalación de 30 segundos, configuración de 2 minutos. Es el mismo módulo que usamos en producción y que generó los números de arriba.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio