Saltar al contenido
Menú

Seguridad

Seguridad del formulario de contacto: spam y bots

Seguridad del formulario de contacto en la práctica: cómo frenar spam y bots, bloquear inyecciones y abusos, y evitar fugas de datos personales.

Publicado
Actualizado
min de lectura
7 min de lectura
Por
Redacción de Kyvrel

La seguridad del formulario de contacto tiene tres tareas: dejar fuera a los bots, impedir que se abuse del formulario y proteger los datos personales que te envían. Ningún truco aislado cubre las tres. Un honeypot, validación en el servidor, límite de envíos y cuidado con el destino de cada mensaje frenan casi todos los problemas sin que los clientes reales noten nada.

El formulario de contacto suele ser la única parte de una web de marketing que acepta datos de desconocidos. Eso lo convierte en la superficie más expuesta y en la que antes llena tu bandeja de basura. Esta guía recorre las capas que incluimos en cada formulario, con ejemplos que puedes pasar a tu desarrollador.

Qué abarca la seguridad del formulario de contacto

Cuando un equipo dice «nos llega spam por el formulario», suele referirse a uno de varios problemas distintos. Conviene nombrarlos, porque cada uno se resuelve de una forma.

  • Spam y bots. Scripts automáticos que envían anuncios, enlaces y basura, a veces miles de veces al día.
  • Abuso del formulario. Atacantes que intentan usarlo para enviar correo a terceros, saturar tu bandeja o sondear tu servidor.
  • Inyección. Datos preparados para salirse de su campo: hacia las cabeceras del correo, un panel de administración o una consulta a la base de datos.
  • Fugas de datos. Mensajes que acaban donde no deben: un buzón sin protección, un archivo de logs, una herramienta externa sin contrato.

Un formulario seguro cubre las cuatro. La mayoría de los formularios problemáticos que revisamos solo cubren la primera, y casi siempre con un CAPTCHA que molesta a las personas reales.

¿Por qué los formularios de contacto atraen tanto spam?

Los formularios son fáciles de encontrar y baratos de atacar. Los bots recorren la web buscando elementos <form> y los envían a ciegas. Les da igual a qué se dedica tu empresa. Y un formulario que manda un correo con cada envío atrae, además, a quien quiere enviar correos que parezcan tuyos.

La buena noticia es que casi todos los bots son simples. Rellenan todos los campos, envían al instante y repiten. Ese comportamiento se detecta con facilidad sin obligar a nadie a resolver acertijos.

Capas que atraviesa un envío en el servidor: límite de tamaño, límite de frecuencia, validación, comprobación del honeypot y entrega segura
Capas que atraviesa un envío en el servidor: límite de tamaño, límite de frecuencia, validación, comprobación del honeypot y entrega segura

Frena a los bots sin castigar a las personas

Primero ponemos comprobaciones baratas y solo añadimos fricción cuando una web de verdad lo necesita.

Añade un campo honeypot

Un honeypot es un campo que las personas no ven y los bots rellenan. Si tiene valor, el envío es de un bot. El truco es responder con un mensaje de éxito normal, para que el bot no aprenda nada.

<!-- Oculto visualmente, sin foco de teclado ni lectores de pantalla -->
<div class="visually-hidden" aria-hidden="true">
  <label for="website">Website</label>
  <input id="website" name="website" tabindex="-1" autocomplete="off">
</div>

En el servidor, un campo website con contenido recibe la misma respuesta de éxito que un contacto real. No se guarda nada y no se avisa a nadie.

Limita por IP sin guardar la IP

Limita cuántos envíos puede hacer un mismo origen en un intervalo, por ejemplo unos pocos cada diez minutos. Guarda un hash con sal de la IP, no la IP en sí. Así te proteges del abuso sin acumular más datos personales.

Un desafío solo cuando haga falta

Si la web sufre bots más listos, añade un desafío de baja fricción como Cloudflare Turnstile o hCaptcha. Usa el modo invisible o gestionado cuando sea posible, y comprueba que la alternativa funciona con teclado y lector de pantalla. Un acertijo nunca debe ser la primera línea de defensa.

Valida todo en el servidor

La validación en el navegador es una comodidad para el usuario. No es seguridad, porque un bot puede enviar la petición que quiera. El servidor debe volver a comprobar cada campo, como recomienda la guía de OWASP sobre validación de entradas.

Una buena validación es estricta y aburrida:

  • Lista cerrada de campos. Rechaza las claves desconocidas en lugar de dejarlas pasar.
  • Limita la longitud. Un nombre no necesita 5000 caracteres. Un mensaje rara vez necesita más de 2000.
  • Comprueba formatos. Un email debe parecer un email. Los campos de selección solo aceptan valores de la lista.
  • Limita el tamaño de la petición antes de procesarla, para que nadie envíe un cuerpo enorme.
// Esquema del servidor, compartido con el formulario del navegador
import { z } from "zod";

export const ContactSchema = z.object({
  name: z.string().trim().min(1).max(120),
  email: z.string().trim().email().max(254),
  company: z.string().trim().max(160).optional(),
  budget: z.enum(["5k-10k", "10k-25k", "25k-50k", "50k-plus", "not-sure"]),
  message: z.string().trim().max(2000).optional(),
  consent: z.literal(true),
  website: z.string().max(200), // honeypot: se revisa tras la validación
}).strict();

Usar el mismo esquema en el navegador y en el servidor mantiene coherentes los mensajes de error. La copia que cuenta es la del servidor.

Bloquea inyecciones y abusos

La validación limita lo que entra. El tratamiento seguro decide qué puede hacer esa entrada una vez dentro.

  • Nunca metas datos del usuario en las cabeceras del correo. Un salto de línea en el campo «nombre» puede añadir destinatarios si llega a la cabecera To o Subject. Envía los avisos a una dirección fija y pon el texto del usuario solo en el cuerpo.
  • Envía avisos en texto plano. Si los mensajes llegan a Slack, Telegram o correo, mándalos como texto plano. Renderizar la entrada como HTML o markdown abre la puerta a enlaces y scripts inyectados.
  • Escapa al mostrar. Cualquier página de administración que liste mensajes debe escapar el contenido, para que un script dentro de un mensaje nunca se ejecute en tu navegador.
  • Usa consultas parametrizadas. Guarda los mensajes mediante tu ORM o sentencias preparadas, nunca concatenando SQL.
  • Comprueba el origen. Acepta envíos solo desde el origen de tu web y con el tipo de contenido esperado. La guía de OWASP sobre CSRF explica las opciones.

Son los mismos principios de nuestro checklist de seguridad web, aplicados a la única parte de la web que acepta datos.

Evita que se filtren los datos enviados

Un formulario es una tubería de datos. Cada sitio donde aterriza un mensaje es un sitio por donde se puede filtrar.

  1. Pide menos. Cada campo opcional son datos que debes proteger. Pregunta solo lo necesario para responder.
  2. Conoce cada destino. Base de datos, correo, CRM, aviso en el chat del equipo. Lístalos y revisa quién tiene acceso a cada uno.
  3. Secretos en el servidor. Las claves de API del CRM o del servicio de avisos nunca deben estar en el código del navegador.
  4. No registres los cuerpos. Los logs de errores que capturan peticiones completas acaban guardando datos personales en una herramienta que nadie audita.
  5. Fija un plazo de conservación. Borra o archiva los mensajes antiguos de forma periódica.
  6. Revisa a tus encargados. Los servicios de formularios y los CRM tratan datos personales por cuenta tuya, así que necesitas contratos con ellos.

El consentimiento y la privacidad, incluido qué poner junto al botón de envío, los tratamos en nuestro artículo sobre el RGPD en tu web.

Adónde va un envío después de validarse: base de datos, aviso al equipo y CRM, cada uno con su propio control de acceso
Adónde va un envío después de validarse: base de datos, aviso al equipo y CRM, cada uno con su propio control de acceso

Cómo hacemos los formularios en Kyvrel

Nuestro propio formulario de contacto sigue el orden anterior, igual que los que construimos para clientes. En resumen, el manejador del servidor hace esto:

  1. Rechaza todo lo que no sea POST.
  2. Rechaza cuerpos de más de 16 KB antes de procesarlos.
  3. Aplica un límite de frecuencia con un hash de IP con sal.
  4. Interpreta el JSON y lo valida con el esquema compartido.
  5. Ante un honeypot relleno, devuelve una respuesta de éxito normal, sin guardar ni enviar nada.
  6. Guarda el contacto y después envía un aviso en texto plano.

Cada paso tiene su test. También probamos el formulario con teclado y lector de pantalla, porque un formulario seguro que parte de la gente no puede usar sigue estando roto.

Lanza un formulario por el que solo pasen clientes reales

Si tu formulario actual llena la bandeja de spam o nadie sabe adónde van los mensajes, merece la pena arreglarlo antes de la próxima campaña. Los formularios seguros vienen de serie en cada web que entregamos. Un chatbot es otra vía de entrada de datos, con su propio spam, abuso de prompts y datos personales que proteger. Las mismas reglas valen si añades un chatbot con IA a tu web. Para calcular el precio con tu alcance, idiomas y extras, usa nuestra calculadora de precio de una web.

Chatbot con IA

Un asistente de chat para tu web que responde con tu propio contenido y pasa la conversación a una persona.

desde12.000 $

7-8 semanas2 rondas de cambios por fase2 fuentes de conocimiento incluidas

  • Reglas de respuesta: qué contesta el chatbot, qué rechaza y cuándo deriva
  • Widget de chat diseñado según tu web, en escritorio y móvil
  • Respuestas basadas solo en tus fuentes de conocimiento, con enlaces
  • Captación de contactos en la conversación, directo a tu correo o CRM
  • Derivación a una persona por correo, con la conversación completa