Cómo evitar el spam en formularios: honeypot, tiempo, CAPTCHA | We.Inc
Frena el spam en el formulario de contacto de tu web con un campo honeypot, una trampa de tiempo y un CAPTCHA gratuito como Turnstile, reCAPTCHA o hCaptcha, verificado en tu servidor. Demo en vivo.
Cómo evitar el spam en el formulario de contacto
Combina primero las comprobaciones baratas y deja las molestas para el final. Añade un campo honeypot oculto que las personas nunca ven pero que los bots rellenan, rechaza los formularios enviados más rápido de lo que una persona podría escribir y, si el spam sigue entrando, añade un servicio CAPTCHA como Turnstile, reCAPTCHA o hCaptcha cuyo token verifique tu servidor.
Defensas contra el spam comparadas
Método
Lo que notan los visitantes
Detiene
Necesita código en el servidor
Campo honeypot
Nada
Bots simples que rellenan todos los campos
Sí, una comprobación de una línea
Trampa de tiempo
Nada
Bots que envían al instante
Sí
Cloudflare Turnstile
Normalmente nada, a veces una casilla
La mayoría de los envíos automatizados
Sí, una llamada a siteverify
reCAPTCHA v3
Nada; recibes una puntuación
La mayoría de los envíos automatizados
Sí, verificar y elegir un umbral
hCaptcha
A veces un rompecabezas
La mayoría de los envíos automatizados
Sí, una llamada a siteverify
Los bots de spam rastrean la web en busca de formularios y los envían automáticamente. Tu servidor no puede ver quién está escribiendo, así que cada defensa funciona detectando un comportamiento que una persona no tendría, o pidiendo a un servicio externo que responda por el visitante. Prueba las dos primeras defensas en la demo y luego copia la comprobación de servidor que las acompaña.
Añade un campo extra con un nombre tentador, como website, y ocúltalo con CSS en lugar de type=hidden.
Añade un campo oculto que guarde la hora en que se mostró el formulario.
En el servidor, descarta cualquier envío en el que la trampa tenga un valor o el intervalo de tiempo sea inferior a unos pocos segundos.
Si el spam continúa, añade un widget CAPTCHA y verifica su token en el servidor antes de guardar o enviar por correo el mensaje.
Acepta y descarta en silencio los envíos atrapados. Mostrar un error le enseña al bot qué debe cambiar.
Dale al campo trampa tabindex="-1" y aria-hidden="true" para que los usuarios de teclado y de lectores de pantalla nunca caigan en él.
Mantén corta la trampa de tiempo, unos tres segundos. El autocompletado del navegador permite a personas reales terminar un formulario rápidamente.
Nunca pongas la clave secreta del CAPTCHA en el código de la página. Solo debe estar en el servidor.
Preguntas frecuentes
¿Qué es un campo honeypot?
Un campo que está en el código del formulario pero oculto para las personas. Los visitantes lo dejan vacío porque nunca lo ven; los bots que rellenan todos los campos que encuentran escriben algo en él, y eso los delata.
¿Hay alguna alternativa gratuita a reCAPTCHA?
Sí. Cloudflare Turnstile y hCaptcha ofrecen planes gratuitos con el mismo esquema: un script y un widget en la página, y luego una llamada desde el servidor a una dirección siteverify con tu clave secreta y el token del visitante. Consulta la página de planes actual de cada proveedor para conocer los límites.
¿reCAPTCHA v3 muestra un rompecabezas?
No. La documentación de Google dice que v3 devuelve una puntuación en la que 1.0 es muy probablemente una interacción legítima y 0.0 muy probablemente un bot, y sugiere empezar con un umbral de 0.5. Tú decides qué hacer con las puntuaciones bajas.
¿Basta el widget por sí solo para frenar el spam?
No. La documentación de Cloudflare afirma claramente que el widget del lado del cliente por sí solo no protege tus formularios. Un bot puede enviar datos directamente a la dirección de tu formulario, así que el servidor debe verificar el token.
¿Por qué sigo recibiendo spam con un honeypot?
Algunos bots usan un navegador real y solo rellenan los campos visibles, y parte del spam lo escriben personas. Añade la trampa de tiempo y después un CAPTCHA. Rechaza también los mensajes llenos de enlaces si tu formulario nunca los necesita.
Por qué las comprobaciones gratuitas van primero
Un honeypot y una trampa de tiempo no le cuestan nada al visitante y atrapan la gran parte del spam que procede de scripts toscos. Un CAPTCHA añade un script de terceros, una entrada en tu aviso de privacidad y a veces un desafío, así que resérvalo para cuando lo necesites.
Oculta la trampa de la forma correcta
Usa CSS que saque el campo de la pantalla en lugar de type="hidden", porque muchos bots se saltan los campos ocultos. Desactiva el autocompletado con autocomplete="off", ya que un navegador que lo rellenara marcaría a una persona real como bot.
MDN señala que los navegadores pueden ignorar autocomplete="off" en los campos de inicio de sesión, así que no llames a la trampa email ni password.
Verifica los tokens CAPTCHA en el servidor
Cada servicio introduce un token en el formulario. Tu servidor envía ese token junto con tu clave secreta a la dirección siteverify del proveedor y solo continúa si la respuesta indica que success es true.
Los tokens de Turnstile son válidos durante 300 segundos y solo pueden comprobarse una vez. Los tokens de reCAPTCHA v3 duran dos minutos, así que solicita uno cuando el visitante envíe el formulario, no al cargar la página.
Copia el honeypot y la trampa de tiempo
El HTML va en tu formulario. La comprobación del servidor se muestra para Node con Express, pero la lógica son tres líneas en cualquier lenguaje.
Formulario con un campo honeypot
La clase .hp saca la trampa de la pantalla. El pequeño script rellena el campo started con la hora actual.
Comprobación en el servidor (Node, Express)
Los bots reciben la misma respuesta que las personas, así que no pueden saber qué comprobación los atrapó.
Cómo añadir Turnstile, reCAPTCHA o hCaptcha
Los tres funcionan de la misma manera. Estos detalles proceden de la documentación de cada proveedor.
Servicios CAPTCHA lado a lado
Turnstile
reCAPTCHA v3
hCaptcha
Script
Se carga desde Google con tu clave de sitio
Widget
<div class="cf-turnstile" data-sitekey>
Sin widget; llama a execute al enviar
<div class="h-captcha" data-sitekey>
Verificar en
challenges.cloudflare.com/turnstile/v0/siteverify
El endpoint de verificación de Google
api.hcaptcha.com/siteverify
Vida del token
300 segundos, un solo uso
Dos minutos
Consulta la documentación del proveedor
Resultado
success true o false
success más una puntuación de 0.0 a 1.0
success true o false
Verificar un token de Turnstile (Node 18 o posterior)
El widget añade a tu formulario un campo llamado cf-turnstile-response. Guarda el secreto en una variable de entorno.
Demo en vivo: honeypot más trampa de tiempo
No se envía nada a ningún sitio. Al pulsar Enviar se ejecutan aquí mismo, en tu navegador, las mismas comprobaciones que haría un servidor.
Tu nombre
Mensaje
Sitio web (deja esto vacío)
Actúa como un bot: rellena el campo oculto
Enviar
Empezar de nuevo
Rellena el formulario y pulsa Enviar para ver qué decide la comprobación del servidor.
Aceptado: la trampa estaba vacía y pasaron {n} segundos. Un formulario real enviaría ahora el mensaje.
Descartado: el campo oculto tenía un valor, así que parece un bot. El visitante seguiría viendo un mensaje de agradecimiento.
Descartado: enviado tras {n} segundos, más rápido que el mínimo de {m} segundos.
Aquí se muestra el campo oculto, con un contorno, para que veas lo que ven los bots.