Blog

Protección de APIs y formularios contra abuso y spam

Actualizado: 12 min de lectura
seguridadrate-limitinganti-spamvalidaciónapiturnstile

Los formularios de contacto, endpoints de login y APIs públicas son blancos frecuentes de abuso: spam, fuerza bruta, scraping y envíos automatizados. La protección efectiva combina varias capas, ninguna por sí sola es suficiente.

Este artículo describe un enfoque en capas para proteger formularios y endpoints en aplicaciones Astro, Laravel y Node.js — el mismo patrón que usa este portafolio en producción.

Capas de protección

  1. Rate limiting: limitar requests por IP en ventana de tiempo.
  2. Honeypot: campo oculto que los bots llenan y los humanos no.
  3. Form timing: detectar envíos más rápidos que un humano (< 3.5s).
  4. Origin check: validar Origin/Referer en producción.
  5. Validación con esquemas: Zod u equivalente en el servidor.
  6. Sanitización: limpiar inputs antes de procesar o almacenar.
  7. CAPTCHA opcional: Cloudflare Turnstile cuando el volumen lo justifica.

Rate limiting

Aplicar en endpoints públicos sensibles:

  • Login y registro: 5 intentos por IP por minuto.
  • Reset de password: 3 por IP por hora.
  • Formulario de contacto: 5 por IP por minuto.
  • APIs sin autenticación: según el caso de uso.

Implementación en memoria para un solo proceso; Redis cuando hay múltiples réplicas. Responder con 429 Too Many Requests y header Retry-After.

Honeypot

Campo oculto con CSS (display: none o position: absolute; left: -9999px). Los bots lo llenan automáticamente; los humanos no lo ven. Si llega con valor, rechazar silenciosamente (responder 200 sin procesar, para no dar pistas al bot).

Form timing

Registrar timestamp al renderizar el formulario (campo oculto o session). Al recibir el POST, rechazar si el tiempo transcurrido es menor a 3–4 segundos. Los bots envían instantáneamente; los humanos tardan al menos unos segundos en leer y completar.

Validación en servidor

Esquemas con Zod (o equivalente) en cada endpoint API:

  • Tipos estrictos: email como email, teléfono con formato, longitud máxima.
  • Campos requeridos vs opcionales explícitos.
  • Rechazar payloads con campos no esperados (strip o reject).
  • Mensajes de error genéricos al cliente; detalle solo en logs del servidor.

Sanitización

  • Strip HTML de campos de texto plano.
  • Normalizar espacios y caracteres de control.
  • Truncar strings que excedan longitud máxima.
  • Nunca interpolar input del usuario en queries SQL ni en templates sin escape.

Origin check

En producción, validar que el header Origin o Referer coincida con el dominio del sitio. Rechazar requests de dominios desconocidos. No es infalible (se puede falsificar), pero filtra bots básicos y scripts cross-origin.

Cloudflare Turnstile

Cuando el volumen de spam justifica fricción adicional, Turnstile de Cloudflare es ligero y respeta privacidad. Se configura con TURNSTILE_SITE_KEY (público) y TURNSTILE_SECRET_KEY (servidor). El servidor verifica el token antes de procesar el formulario.

Flujo completo en un endpoint

  1. Rate limit check → 429 si excede.
  2. Honeypot check → 200 silencioso si lleno.
  3. Form timing check → 400 si muy rápido.
  4. Origin check → 403 si origen inválido.
  5. Turnstile verification (si configurado) → 400 si inválido.
  6. Validación Zod → 400 con errores de campo.
  7. Sanitización → procesar.

Errores frecuentes

  • Confiar solo en validación del frontend.
  • Rate limiting solo en login, no en contacto ni webhooks.
  • Honeypot visible o con tabindex accesible (los lectores de pantalla lo llenan).
  • Responder 403 al honeypot (el bot aprende y adapta).
  • Loguear payloads completos con emails y teléfonos (PII en logs).
  • Rate limit en memoria con 3 réplicas (cada una tiene su propio contador).

Conecta con auditoría de seguridad, ciberseguridad y APIs REST .

Preguntas frecuentes

¿El honeypot basta contra bots?

No solo. El honeypot filtra bots básicos, pero conviene combinarlo con rate limiting, timing de formulario y, en producción, un CAPTCHA como Turnstile.

¿Dónde aplicar rate limiting?

En endpoints públicos: login, registro, reset de password, formularios de contacto, webhooks y APIs sin autenticación. Por IP y, si aplica, por usuario autenticado.

¿Validar en frontend o backend?

En ambos, pero el backend es obligatorio. La validación del frontend mejora UX; la del backend es la que importa para seguridad.

¿Turnstile o reCAPTCHA?

Turnstile de Cloudflare es ligero, respeta privacidad y se integra sin fricción. reCAPTCHA v3 funciona pero depende de Google. La elección depende del stack y la política de privacidad.

¿Rate limiting en memoria escala?

Para un solo proceso sí. Con múltiples réplicas hace falta Redis u otro store compartido. En desarrollo, memoria es suficiente.