Formulario de contacto sin CAPTCHA: qué detiene el spam de verdad
En nuestra página de contacto no hay CAPTCHA. Esto es lo que corre en su lugar, lo que detuvo cuando lo pusimos a prueba, lo que deja pasar y por qué un acertijo antes del botón de enviar suele ser la opción más cara para un negocio chico.
Más de la mitad del tráfico de la web ya es de máquinas. Imperva contó 53 por ciento de accesos automatizados en 2025, contra 51 por ciento el año anterior. Aun así, en nuestra página de contacto no hay CAPTCHA.
Fue una decisión con razones, y aquí están: lo que hace el formulario en su lugar, la prueba que le aplicamos y la parte que queda abierta.
Lo que cuesta un CAPTCHA
Un acertijo antes del botón de enviar parece una medida menor. Trae tres cuentas separadas.
La primera la pagan los visitantes que ven poco. El W3C publicó su postura en una nota del 16 de diciembre de 2021, "Inaccessibility of CAPTCHA". La frase central: un patrón de diseño que da por normal varios intentos del usuario excluye desde el arranque. La alternativa de audio de reCAPTCHA v2 necesita más de ocho pasos según el instructivo del propio Google, desde encontrar el botón hasta volver a escribir cuando la sesión ya venció. Lo que escribimos sobre esto está en nuestro artículo sobre el sitio web accesible.
La segunda la paga tu aviso de privacidad. reCAPTCHA manda datos de tu visitante a Google antes de que esa persona haya aceptado nada, y esos datos salen de México. La LFPDPPP publicada el 20 de marzo de 2025 y vigente desde el día siguiente mantiene el principio de información: el titular tiene que poder saber qué pasa con sus datos. Desde ese mismo día la autoridad ya es la Secretaría Anticorrupción y Buen Gobierno en lugar del INAI. Si tu sitio también recibe visitas desde Europa, allá la barra está más alta: un tribunal federal austriaco resolvió en 2024 que reCAPTCHA queda fuera de lo técnicamente necesario, así que ahí requiere consentimiento.
La tercera la paga tu operación. Cada elemento frente al botón de enviar cuesta solicitudes. Con cinco solicitudes al mes, una perdida se nota de inmediato. Con quinientas, desaparece en el promedio. Los negocios chicos viven en el primer caso.
Lo que corre en nuestro formulario
| Pieza | Qué hace | De dónde viene |
|---|---|---|
| Campo trampa | Un campo invisible. Si llega lleno, el envío se descarta | Plugin de formularios, tipo honeypot |
| Token de un solo uso | Cada formulario trae un token ligado a la sesión. Si falta o no coincide, el proceso se detiene | Grav, form-nonce |
| Bloqueo de reenvío | El mismo identificador de formulario se rechaza la segunda vez | refresh_prevention: true |
| Opciones fijas | Dos de las respuestas son listas con valores cerrados. Cualquier otro valor falla la validación | tipo select con options |
| Casilla obligatoria | Una casilla que tiene que quedar marcada | tipo checkbox con required |
| Validación en el servidor | Todas las reglas corren en el servidor. Lo que pase en el navegador no decide la aceptación | Grav, validate |
| Marca de tiempo, desde el 27/09 | El formulario lleva firmada la hora en que se entregó la página. Quien envía en menos de tres segundos o altera el valor suma puntos | plugin propio, tipo zeitstempel |
| Revisión de contenido, desde el 27/09 | Enlaces acortados, fórmulas de baja de los envíos masivos, frases típicas de fraude y venta de enlaces, remitentes conocidos y el parecido con mensajes ya apartados suman puntos. Con tres puntos el mensaje va a cuarentena | plugin propio, paso spamcheck |
Ocho validaciones, y ninguna le pide nada al visitante. El costo para una persona es de cero segundos de espera, cero clics extra y cero datos entregados a terceros.
El campo trampa por dentro
Se define con dos líneas en el encabezado de la página:
- name: hinweis
type: honeypot
En el código fuente sale un campo con cuatro propiedades que van juntas:
<input aria-hidden="true" tabindex="-1" autocomplete="off"
style="visibility:hidden;position:absolute;height:1px;width:1px"
class="form-honeybear" name="data[hinweis]" value="" />
aria-hidden lo saca del orden de lectura, tabindex="-1" lo saca del orden de tabulación, autocomplete="off" evita que el navegador lo llene solo y el estilo lo saca de la pantalla. Una persona se topa con este campo por ninguno de esos cuatro caminos. Un programa que lee el código y llena todo se topa con él de inmediato.
Un detalle pesa más de lo que parece: un campo trampa escondido con display:none lo detectan algunos autocompletadores. La combinación de visibility:hidden con un recuadro de un pixel es la solución más usada, porque para el programa sigue pareciendo un campo normal.
Medido
Las descripciones salen baratas, así que le mandamos un envío a nuestro propio formulario con todos los campos obligatorios, un token válido y el campo trampa lleno. El servidor contestó:
HTTP 200
<div class="notices error red"><p>Are you a bot?</p></div>
El envío se descartó, no se guardó nada y no salió ningún aviso. La validación funciona.
En la misma prueba salió otra cosa: el mensaje está en inglés, en un sitio que corre en alemán, inglés y español. Viene del plugin de formularios como cadena fija y nunca pasa por los archivos de idioma. Una persona lo ve pocas veces, y con un falso positivo basta. Ya quedó en nuestra lista.
Lo que sí pasa
La parte honesta, y es corta.
Los ataques dirigidos pasan. Quien revisa un formulario a mano reconoce el campo trampa en dos minutos y la próxima vez lo deja vacío. La protección sirve contra programas que llenan formularios a ciegas en miles de sitios, que es donde está el volumen.
Los agentes de IA son un caso nuevo. Imperva describe para 2026 una categoría propia: sistemas que resuelven tareas para personas y dibujan las páginas como lo haría un navegador. Un agente así ve el campo invisible igual de poco que un ser humano.
La prospección escrita a mano pasa la primera vez. El mensaje de la agencia que te quiere vender enlaces es técnicamente una solicitud correcta. Cuando lo marcamos como spam, el filtro ya conoce al remitente y el texto, y el segundo cae en cuarentena.
Cuántos intentos rechaza el campo trampa no lo sabemos, y la razón nos gusta: no los contamos. Llevar esa estadística significaría registrar y guardar accesos, y eso es más tratamiento de datos del que la pregunta merece.
Lo que sí contamos fue lo que pasó, y ahí nos equivocamos. Hasta el 27 de septiembre aquí decía que en la carpeta había trece solicitudes reales. Eso era falso. El 19 de septiembre había trece envíos: cuatro pruebas nuestras y nueve mensajes de publicidad o fraude. Los nueve habían pasado las seis validaciones que corrían en ese momento. Entre ellos había ofertas de enlaces, una supuesta base de datos de empresas a punto de cerrar, una historia de herencia y un enlace acortado a una página de citas para adultos. Queja de alguien que no haya podido enviar el formulario seguimos sin tener ninguna.
Lo que cambió el 27 de septiembre
Esos nueve mensajes nos mostraron dónde está el hueco. Venían de programas que dibujan la página como un navegador o de personas, y los dos llenan el formulario tal como está pensado. Los delató el texto: enlaces acortados, la fórmula de baja de un envío masivo, los mismos remitentes una y otra vez.
Por eso ya corren los escalones 1 y 3 de la tabla de abajo. Cada mensaje suma puntos por señales así y por enviarse sospechosamente rápido. Un solo enlace nunca cuenta, porque los interesados mencionan su sitio actual. Con tres puntos el mensaje va a cuarentena. Quien lo mandó ve la misma confirmación que cualquiera y se queda sin saber qué lo delató. Si ahí cae una solicitud real, la regresamos con un clic, y su remitente entra en una lista que el filtro deja pasar desde entonces. Lo que está en cuarentena se borra solo a los ocho meses.
El filtro aprende sobre la marcha. Cuando está muy seguro, pone al remitente en una lista de bloqueo, y lo mismo pasa con cada mensaje que marcamos como spam a mano. Además compara cada mensaje nuevo con todo lo que hay en cuarentena, así que la misma oferta con otro nombre y otra dirección se nota por el parecido.
También lo medimos. Volvimos a mandar por el formulario los once mensajes de publicidad o fraude que habían llegado hasta el 26 de septiembre, junto con cuatro solicitudes escritas por nosotros como las mandaría un interesado. Diez de los once cayeron directo en cuarentena. El restante, una oferta muy amable de intercambio de enlaces sin ningún enlace, pasó. Después de un clic en "marcar como spam" el filtro detuvo el mismo mensaje la segunda vez. Las cuatro solicitudes llegaron a la bandeja de entrada.
Las listas del filtro las escribimos con esos once mensajes enfrente, así que con publicidad nueva el porcentaje va a ser menor. Para la cuarentena guardamos cada mensaje tal como llegó, junto con los motivos. Direcciones IP seguimos sin guardar.
Lo que agregamos con más presión
En este orden, porque cada escalón cuesta más que el anterior:
| Escalón | Medida | Costo para el visitante |
|---|---|---|
| 1 | Revisión de tiempo, apartar envíos sospechosamente rápidos | ninguno |
| 2 | Límite por dirección IP y por hora en el servidor web | ninguno |
| 3 | Revisión de contenido por enlaces y patrones conocidos | ninguno, los falsos positivos los sacamos de la cuarentena |
| 4 | CAPTCHA sin acertijo, Friendly Captcha o Altcha | un cálculo corto en segundo plano |
| 5 | CAPTCHA clásico de imágenes | tiempo, frustración y solicitudes perdidas |
El escalón 5 está ahí para que la lista quede completa. Desde el 27 de septiembre corren en nuestro formulario los escalones 1 y 3. Para el 2 el volumen es muy chico: once mensajes en ocho semanas.
Lo que puedes hacer hoy
- Revisa qué carga tu formulario desde terceros. Basta con ver el código fuente: si aparece una llamada a
google.com/recaptcha, hay una conexión a Google en cada visita, incluso con quien jamás envía el formulario. - Checa si ya existe un campo trampa. Los plugins de formularios más usados lo traen, y con frecuencia solo está apagado.
- Mándate una solicitud de prueba y revisa si llega, a dónde llega y cuánto tarda. Los formularios fallan en silencio.
- Cuenta tus solicitudes de los últimos tres meses. Debajo de veinte al mes, casi ningún CAPTCHA vale una sola solicitud real perdida.
- Si el CAPTCHA se queda, decláralo en tu aviso de privacidad y elige uno que funcione sin acertijo visual.
Si tienes duda de qué manda tu formulario y a dónde: escríbenos con la dirección de tu sitio. Revisamos el código fuente y te decimos qué trae. Esa parte no cuesta.
Fuentes
- W3C: Inaccessibility of CAPTCHA, 16 de diciembre de 2021
- Imperva: Bad Bot Report 2026
- Garrigues: la nueva Ley Federal de Protección de Datos Personales en Posesión de los Particulares
- Proliance sobre el papel de Google en reCAPTCHA desde el 2 de abril de 2026
- Grav: plugin de formularios con el tipo de campo honeypot
- Friendly Captcha sobre accesibilidad de los CAPTCHA
Vigencia de este artículo
Corregido: entre los primeros trece envíos no había ninguna solicitud real, aquí decía lo contrario. Nuevas en el formulario: marca de tiempo, revisión de contenido y cuarentena.
Preguntas frecuentes sobre el spam en formularios
¿Qué es un campo trampa?
Un campo de entrada adicional que queda invisible para las personas y que para un programa se ve como cualquier otro. Un script que llena todos los campos llena también ese, y lo que llegue ahí se descarta. El visitante nunca lo ve, un lector de pantalla lo omite y la tecla de tabulación no llega a él.
¿El CAPTCHA es obligatorio en México?
Ninguna norma lo exige. La LFPDPPP te obliga a proteger los datos que recabas y a informar en tu aviso de privacidad qué haces con ellos. Un formulario que valida del lado del servidor, rechaza intentos masivos y no publica nada cumple con lo primero. Quitar el acertijo ayuda con lo segundo, porque un CAPTCHA de Google manda datos de tu visitante a un tercero en el extranjero antes de que esa persona acepte algo.
¿Puedo usar Google reCAPTCHA sin más?
Desde el 2 de abril de 2026 Google actúa como encargado del tratamiento, lo que aclara su papel. Siguen abiertas dos cosas: los datos salen del país y no hay una lista completa de lo que se recolecta. Con la LFPDPPP vigente desde el 21 de marzo de 2025, cualquier tratamiento por parte de un tercero tiene que quedar reflejado en tu aviso de privacidad. Si además vendes en Europa, allá hace falta consentimiento expreso.
¿El campo trampa detiene a los agentes de IA?
A una parte. Un agente que lee el código fuente y llena los campos que encuentra cae de inmediato. Un agente que dibuja la página como un navegador y solo toca campos visibles pasa sin problema. Contra el segundo ayudan las validaciones de tiempo y de contenido, y al final la lectura de una persona.
¿Y los límites por IP y las listas de bloqueo?
Un límite por dirección IP y por hora va en el servidor web y no cuesta ni una línea dentro del formulario. Vale la pena cuando llegan muchos intentos en poco tiempo. Una lista de bloqueo de remitentes la llevamos nosotros desde el 27 de septiembre: cada mensaje que marcamos como spam pone a su remitente en ella, y el siguiente que llegue de ahí cae en cuarentena.
¿Qué pasa con los mensajes en cuarentena?
Se quedan ahí, sin aviso y fuera de la lista de solicitudes. Quien los mandó ve la misma confirmación que con cualquier solicitud. Si ahí cae una solicitud real, la regresamos con un clic. A los ocho meses se borran solos.
Si de plano necesito un CAPTCHA, ¿cuál?
Uno que funcione sin acertijo. Friendly Captcha resuelve una tarea en segundo plano y está certificado contra WCAG 2.2 nivel AA, Altcha hace lo mismo como software libre en tu propio servidor y Cloudflare Turnstile es el punto medio cómodo. Antes de elegir, cuenta cuánto spam recibes en realidad.