Formulários de contato, endpoints de login e APIs públicas são alvos frequentes de abuso: spam, força bruta, scraping e envios automatizados. A proteção eficaz combina várias camadas; nenhuma sozinha basta.
Este artigo descreve uma abordagem em camadas para proteger formulários e endpoints em aplicações Astro, Laravel e Node.js — o mesmo padrão que este portfólio usa em produção.
Camadas de proteção
- Rate limiting: limitar requests por IP em janela de tempo.
- Honeypot: campo oculto que bots preenchem e humanos não.
- Form timing: detectar envios mais rápidos que um humano (< 3.5s).
- Origin check: validar Origin/Referer em produção.
- Validação com esquemas: Zod ou equivalente no servidor.
- Sanitização: limpar inputs antes de processar ou armazenar.
- CAPTCHA opcional: Cloudflare Turnstile quando o volume justifica.
Rate limiting
Aplicar em endpoints públicos sensíveis:
- Login e registro: 5 tentativas por IP por minuto.
- Reset de senha: 3 por IP por hora.
- Formulário de contato: 5 por IP por minuto.
- APIs sem autenticação: conforme o caso de uso.
Implementação em memória para um único processo; Redis quando há múltiplas réplicas. Responder com 429 Too Many Requests e header Retry-After.
Honeypot
Campo oculto com CSS (display: none ou position: absolute; left: -9999px). Bots preenchem automaticamente; humanos não veem. Se chegar com valor, rejeitar silenciosamente (responder 200 sem processar, para não dar pistas ao bot).
Form timing
Registrar timestamp ao renderizar o formulário (campo oculto ou session). Ao receber o POST, rejeitar se o tempo for menor que 3–4 segundos. Bots enviam instantaneamente; humanos levam alguns segundos para ler e preencher.
Validação no servidor
Esquemas com Zod (ou equivalente) em cada endpoint API:
- Tipos estritos: email como email, telefone com formato, comprimento máximo.
- Campos obrigatórios vs opcionais explícitos.
- Rejeitar payloads com campos inesperados (strip ou reject).
- Mensagens de erro genéricas ao cliente; detalhe só nos logs do servidor.
Sanitização
- Remover HTML de campos de texto simples.
- Normalizar espaços e caracteres de controle.
- Truncar strings que excedam o comprimento máximo.
- Nunca interpolar input do usuário em queries SQL nem em templates sem escape.
Origin check
Em produção, validar que o header Origin ou Referer corresponda ao domínio do site. Rejeitar requests de domínios desconhecidos. Não é infalível (pode ser falsificado), mas filtra bots básicos e scripts cross-origin.
Cloudflare Turnstile
Quando o volume de spam justifica fricção extra, o Turnstile da Cloudflare é leve e respeita privacidade. Configura-se com TURNSTILE_SITE_KEY (público) e TURNSTILE_SECRET_KEY (servidor). O servidor verifica o token antes de processar o formulário.
Fluxo completo em um endpoint
- Rate limit check → 429 se exceder.
- Honeypot check → 200 silencioso se preenchido.
- Form timing check → 400 se muito rápido.
- Origin check → 403 se origem inválida.
- Turnstile verification (se configurado) → 400 se inválido.
- Validação Zod → 400 com erros de campo.
- Sanitização → processar.
Erros frequentes
- Confiar só na validação do frontend.
- Rate limiting só no login, não em contato nem webhooks.
- Honeypot visível ou com
tabindexacessível (leitores de tela preenchem). - Responder 403 ao honeypot (o bot aprende e adapta).
- Logar payloads completos com emails e telefones (PII nos logs).
- Rate limit em memória com 3 réplicas (cada uma tem seu próprio contador).
Conecte com auditoria de segurança, cibersegurança e APIs REST .