O que protege realmente um formulário: CAPTCHA, honeypot, armadilha de tempo, CSRF
A maioria dos formulários de contacto recorre a um único truque contra o spam, e muitos desses truques só travam os bots mais simples. O que trava cada camada de proteção, quanto custa e que combinação faz sentido.
O spam através de formulários de contacto raramente vem de uma pessoa a escrever à mão. Na maior parte dos casos, é software que encontra formulários, preenche todos os campos e envia o resultado – milhares de vezes. Existem várias defesas, e atuam em pontos muito diferentes. Saber o que cada uma faz realmente ajuda a evitar dois erros: um formulário sem proteção real e um formulário tão fortemente vigiado que as pessoas reais desistem.
- Honeypot: bots simples que preenchem todos os campos
- Armadilha de tempo: scripts que submetem logo após o carregamento
- CAPTCHA: a maioria da automatização genérica
- Token CSRF: pedidos enviados diretamente para o endpoint
- Limitação de frequência: inundações a partir de uma única origem
- Proof-of-work: submissões massivas baratas, sem rastreio nem quebra-cabeças
- Verificações do lado do servidor: tudo o que contorna o navegador
- Os bots direcionados ignoram-no; se mal ocultado, os leitores de ecrã anunciam-no
- Bots que esperam; sem uma assinatura do lado do servidor, é fácil de falsificar
- Um obstáculo para todos, barreiras de acessibilidade, muitas vezes de terceiros; existem serviços de resolução
- Os bots que carregam primeiro a página também obtêm um token válido
- Spam distribuído por muitos endereços IP
- Um remetente determinado com capacidade de computação; requer JavaScript
- Nada, sozinhas – mas, sem elas, todas as outras camadas são decoração
Honeypot e armadilha de tempo: filtros invisíveis
Um honeypot é um campo adicional que as pessoas nunca veem, como um campo chamado «website» ocultado com CSS. Os bots simples preenchem todos os campos, pelo que um honeypot preenchido indica automatização e o servidor pode descartar discretamente a mensagem. Os bots escritos para o seu sítio, ou os que renderizam a página como um navegador, ignoram-no. Oculte-o corretamente: um campo apenas deslocado para fora do ecrã pode ser anunciado pelos leitores de ecrã, alcançado com a tecla Tab ou preenchido pelo preenchimento automático. Utilize aria-hidden, tabindex -1 e autocomplete off, bem como uma etiqueta neutra que peça a quem lá chegue que o deixe vazio.
Uma armadilha de tempo regista quando o formulário foi entregue e rejeita as submissões que chegam com uma rapidez inverosímil. As pessoas precisam de alguns segundos para ler e escrever; muitos scripts enviam numa fração de segundo. O carimbo temporal tem de ser verificado no servidor e protegido contra manipulação, por exemplo assinado ou guardado na sessão – um simples campo de tempo oculto é reescrito sem mais pelo bot. Mantenha o limiar baixo, pois o preenchimento automático também torna rápidas as pessoas reais. Os bots que simplesmente esperam conseguem passar: uma armadilha de tempo é um filtro, não uma muralha.
CAPTCHA: eficaz, mas não gratuito
Um CAPTCHA pede uma prova de que não está em ação um bot – desde quebra-cabeças com imagens até verificações executadas em segundo plano; serviços comuns incluem reCAPTCHA, hCaptcha, Cloudflare Turnstile e Friendly Captcha. Trava a maior parte da automatização genérica, e é por isso que é tão popular. Mas cada quebra-cabeças visível é um obstáculo perante o qual alguns visitantes desistem, e a maioria dos serviços carrega um script de terceiros, o que levanta questões de privacidade e de consentimento. Um CAPTCHA só ajuda, além disso, se estiver bem configurado: uma chave de site de teste pública, um widget sem o respetivo script ou um token que o servidor nunca verifica parecem proteção, mas não o são. Uma verificação gratuita em formexposed.com assinala esses erros a partir do exterior.
A acessibilidade faz parte desse custo. Os quebra-cabeças com imagens excluem as pessoas cegas e muitas pessoas com baixa visão, as alternativas áudio não ajudam as pessoas surdocegas e as tarefas lógicas complicadas sobrecarregam as pessoas com deficiências cognitivas. O critério de sucesso 1.1.1 das WCAG 2.2 exige uma alternativa em texto que descreva a finalidade do CAPTCHA e formas alternativas para diferentes sentidos. As verificações em segundo plano evitam a maior parte disto, mas, quando ficam desconfiadas, a alternativa é muitas vezes, de novo, um quebra-cabeças visual – teste esse percurso com um teclado e um leitor de ecrã.
Token CSRF: proteção contra falsificação, não contra spam
Um token CSRF é um valor aleatório que o servidor coloca no formulário e espera receber de volta. Foi concebido contra a falsificação de pedidos entre sítios (cross-site request forgery), em que outro sítio Web faz com que o navegador de um visitante envie um pedido que o visitante nunca pretendeu. Num formulário de contacto público, tem um efeito secundário: os bots que enviam diretamente para o endereço do formulário sem carregar a página são rejeitados. Qualquer bot que obtenha a página e devolva o token consegue passar. A maioria das frameworks e dos plugins de formulários inclui de qualquer forma tokens CSRF – mantenha-os ativos, mas não os conte como proteção antispam.
O que tem de acontecer no servidor
- Valide de novo cada campo no servidor: campos obrigatórios, comprimento, formato do e-mail e ausência de quebras de linha nos campos que acabam nos cabeçalhos do correio.
- Verifique os tokens CAPTCHA e de proof-of-work em cada submissão, junto do serviço emissor ou no seu próprio código, e rejeite os tokens reutilizados.
- Limite as submissões por endereço IP e janela temporal. Isto trava as inundações a partir de uma origem; o spam distribuído por muitos endereços exige outras camadas.
- Pondere o proof-of-work: antes de enviar, o navegador resolve uma pequena tarefa de cálculo. Os visitantes não veem nenhum quebra-cabeças e nada é rastreado, mas a submissão massiva torna-se dispendiosa.
Uma combinação sensata: duas ou três camadas
- 1Comece pelas camadas invisíveis: um honeypot acessível e uma armadilha de tempo assinada, ambos verificados no servidor.
- 2Acrescente uma limitação de frequência por endereço IP, para que uma única origem não possa inundar o formulário.
- 3Se o spam direcionado continuar a passar, acrescente proof-of-work ou um CAPTCHA – de preferência um sem quebra-cabeças visível e com uma alternativa acessível.
- 4Mantenha o token CSRF que a sua framework fornece – como bónus, não como defesa.
- 5Teste o resultado como visitante – só com o teclado, com um leitor de ecrã, num telemóvel – e verifique se as mensagens reais continuam a chegar.
Em muitos sítios, honeypot, armadilha de tempo e limitação de frequência, em conjunto, já eliminam a maior parte do spam genérico sem qualquer obstáculo visível; um CAPTCHA é a reserva para quando isso não basta. No WordPress, o plugin gratuito da formexposed combina honeypot, verificação de tempo e proof-of-work sem precisar da Google. Para ver o que o seu formulário mostra a partir do exterior – que camadas estão presentes, se um CAPTCHA está configurado de forma eficaz –, uma verificação gratuita em formexposed.com só precisa de um domínio, sem conta. Não consegue ver o código do seu servidor, pelo que a parte do lado do servidor continua a ser tarefa sua.