Um formulário de contato ou uma API pública sem controle é como um prédio sem porteiro: qualquer um entra, deixa lixo ou tenta forçar a porta. Spam, força bruta e scraping não são “ruído menor”: lotam caixas de entrada, consomem cota de email e podem derrubar um endpoint numa sexta à tarde.
Este artigo explica uma abordagem em camadas — o mesmo padrão que este portfólio usa em produção com Astro, e aplicável a Laravel e Node — para que uma pessoa não técnica entenda o porquê, e um técnico tenha checklist, ordem de checagens e erros a evitar.
Por que importa para o negócio
Cada lead falso custa tempo de vendas. Cada tentativa de login sem limite é uma loteria contra credenciais vazadas. Cada webhook ou endpoint “aberto” é superfície de abuso. Proteger não é paranoia: é manter o canal útil para humanos reais e caro para bots.
- Caixa de entrada usável: menos spam = mais respostas a clientes reais.
- Disponibilidade: rate limit evita que um script derrube o servidor.
- Confiança: validar no servidor reduz lixo no CRM e tickets inventados.
- Conformidade prática: menos PII de atacantes em logs e bases.
Conceitos-chave (simples + técnicos)
O porteiro em camadas
Nenhuma camada sozinha basta. O honeypot pega bots toscos; o rate limit freia o volume; o timing detecta envios desumanos; validação e sanitização cuidam do que entra; Turnstile adiciona atrito só quando preciso. Como um prédio: recepção, câmera, chave e alarme — não só uma placa de “proibido”.
| Camada | O que bloqueia | Resposta típica |
|---|---|---|
| Rate limiting | Volume / força bruta | 429 + Retry-After |
| Honeypot | Bots que preenchem tudo | 200 silencioso (sem processar) |
| Form timing | Envios < ~3.5s | 400 |
| Origin check | Scripts cross-origin básicos | 403 |
| Turnstile | Bots mais sofisticados | 400 se o token for inválido |
| Zod + sanitizar | Lixo e payloads estranhos | 400 com erros de campo |
Rate limiting
Limita requests por IP (e, se aplicável, por usuário) numa janela de tempo. Em um só processo, memória basta; com várias réplicas é preciso Redis ou outro store compartilhado. Exemplos orientativos: login 5/min, reset de senha 3/hora, contato 5/min.
Honeypot e timing
O honeypot é um campo oculto (display: none ou fora da tela) que humanos não veem. Se chegar preenchido, rejeite em silêncio (200 sem processar) para não treinar o bot. O timing guarda um timestamp no render e rejeita envios mais rápidos que um humano razoável.
Validação, sanitização e origem
A validação do frontend melhora a UX; a do servidor é a que importa. Esquemas (Zod ou equivalente), strip de HTML em texto plano, comprimentos máximos e, em produção, checar Origin/Referer. Não é infalível, mas filtra muito ruído barato.
Guia prático: fluxo num endpoint
- Rate limit check →
429se exceder. - Honeypot check →
200silencioso se o campo oculto tiver valor. - Form timing check →
400se for rápido demais. - Origin check →
403se a origem não for a do site. - Turnstile (se configurado) →
400se o token falhar. - Validação com esquema →
400com erros de campo. - Sanitização → processar (email, CRM, fila).
Honeypot bem feito
- Oculto com CSS, não com
type="hidden"óbvio quando puder evitar. - Nome enganoso (
website,company_url) — nãohoneypot. tabindex="-1"eautocomplete="off"; não deve ser acessível acidentalmente a leitores de tela.- Se estiver preenchido: responder sucesso falso, não
403explícito.
Cloudflare Turnstile
Quando o volume de spam justifica atrito extra, o Turnstile é leve e respeita privacidade frente a alternativas mais agressivas. TURNSTILE_SITE_KEY no cliente; TURNSTILE_SECRET_KEY só no servidor. O servidor verifica o token antes de processar.
Erros frequentes
- Confiar só na validação do frontend.
- Rate limit só no login, não no contato nem em endpoints públicos.
- Honeypot visível, com label real, ou focável por teclado/leitores.
- Responder
403ao honeypot (o bot aprende e se adapta). - Logar payloads completos com emails e telefones (PII em logs).
- Rate limit em memória com 3 réplicas (cada uma tem seu contador).
- Mensagens de erro que revelam se um email “existe” no sistema.
Checklist de proteção
- Lista de endpoints públicos sensíveis (login, contato, reset, webhooks).
- Rate limit com limites documentados e
Retry-After. - Honeypot + timing em formulários HTML.
- Checagem Origin/Referer em produção.
- Esquema de validação no servidor + sanitização.
- Turnstile opcional quando o spam justificar.
- Store compartilhado (Redis) se houver mais de uma réplica.
- Logs sem PII desnecessária; métricas de 429/400 para detectar ataques.
Conecta com auditoria de segurança, cibersegurança e APIs REST .