← Voltar para artigos

Site sob ataque: como travamos um ataque de spam que mandava e-mails em nome da empresa

Oitenta pedidos falsos em três dias, cada um com um e-mail de confirmação para uma pessoa real. Como eu descobri, o que fiz primeiro, o captcha grátis da Cloudflare e o checklist para o seu site.

Segurança · Johnny Helder · 27 de setembro de 2026 · 9 min de leitura

Resposta em 30 segundos. Se o seu site manda um e-mail automático de "recebemos o seu pedido" para o endereço que o visitante digita, qualquer robô pode usar o seu formulário para mandar e-mails assinados pelo seu domínio. Foi o que aconteceu com uma cliente minha em setembro de 2026. O primeiro passo é desligar esse e-mail. Depois vêm o filtro, a validação, um captcha invisível e grátis (o Cloudflare Turnstile) e a limpeza. Depois do bloqueio, o robô tentou de novo 124 vezes e não passou nenhuma. O checklist está no fim.

O que aconteceu

A minha cliente tem uma empresa de animação de eventos e casamentos em Portugal. O site novo foi ao ar em meados de setembro, com um formulário de pedido de orçamento que grava tudo numa base de dados, avisa a dona por e-mail e manda ao cliente uma confirmação simpática, "Recebemos o seu pedido".

Num sábado, os pedidos começaram a chegar em série. Num dia normal entram um ou dois. Naquele sábado entraram 54. No domingo de manhã, mais nove antes das nove horas.

Todos tinham o mesmo nome, RobertLow. A mensagem era sempre a mesma pergunta, "queria saber o seu preço", cada vez numa língua diferente. Lituano, armênio, bengali, basco, zulu, havaiano. O telefone tinha onze dígitos inventados. A data do evento ficava entre 1980 e 1988, e às vezes era uma data que não existe, como o dia zero de um mês. O número de convidados ia até 971.

E o e-mail era sempre de uma pessoa real. Contas do Gmail, do Yahoo, de um provedor alemão, de uma universidade americana, de um órgão de governo dos Estados Unidos. Endereços tirados de listas vazadas.

Foi um ataque hacker?

Foi um ataque, mas não uma invasão. Ninguém entrou no servidor, ninguém roubou senha nem base de dados. O robô usou a porta da frente, o formulário público, como qualquer visitante, só que dia e noite e sem se cansar. É o ataque automatizado mais comum contra sites de pequenas empresas, e é por isso que vale entender como ele funciona.

Por que isso é pior do que parece

O lixo no painel de pedidos é chato. Estraga a taxa de conversão, estraga o tempo médio de resposta e enche o celular de notificações. Mas isso se limpa numa tarde.

O problema grave era outro. Cada pedido falso disparava a confirmação automática. Ou seja, o site da minha cliente mandou cerca de 80 e-mails, com o nome dela e o domínio dela, para pessoas que nunca tinham ouvido falar da empresa.

E esses e-mails saíram perfeitos. Assinatura digital válida, domínio verificado, tudo o que um servidor de e-mail confere para decidir se a mensagem é legítima. Para quem recebeu, foi a empresa que escreveu.

Se algumas dessas pessoas clicarem em "marcar como spam", o domínio perde reputação. E o domínio que manda a confirmação é o mesmo que manda as propostas de verdade. Uma proposta que cai na caixa de spam de um casal é um casamento perdido, e ninguém fica sabendo por quê.

No xadrez, antes de pensar no ataque, você fecha a casa por onde o adversário está entrando. Aqui a casa aberta era um e-mail que respondia a qualquer um.

Como eu descobri o robô

Não precisei de ferramenta cara. Precisei de três lugares.

A base de dados. Uma consulta simples, pedidos por dia, mostrou o salto de um ou dois para 54. Outra, pedidos por IP, mostrou que quase todos vinham do mesmo endereço, um servidor na Romênia, num provedor muito associado a abuso. Dois pedidos anteriores, de dois dias antes, vinham de um servidor na Lituânia. Mesmo robô, outro IP.

Os logs do servidor web. Cada envio do robô eram três linhas. Uma visita à página inicial sem segurança, uma visita à página com segurança e o envio do formulário, tudo em menos de um segundo. Nenhum pedido de imagem, de estilo ou de JavaScript. Ninguém preenche nome, telefone, data e convidados em menos de um segundo, e nenhum navegador de verdade abre uma página sem carregar as imagens.

Tinha um detalhe mais. Todos os envios do robô chegavam num protocolo antigo, HTTP/1.0. Fui conferir as pessoas reais que usaram o formulário naquele mês. Todas chegaram em HTTP/1.1. Todos os envios em HTTP/1.0 eram robôs.

Os relatórios de e-mail. Os grandes provedores mandam todos os dias um relatório com quantas mensagens do seu domínio receberam e se passaram na verificação. Esse relatório confirmou o que eu temia. As confirmações tinham chegado aos destinatários, com a assinatura válida.

Por que o filtro que já existia não pegou

Esse site já tinha um filtro de spam. Dias antes tinham chegado os primeiros robôs, vendedores de software em inglês com um link na mensagem, e eu montei um sistema de pontos. Link na mensagem soma pontos. Conversa de vendedor soma. Inglês com link soma. Telefone curto soma. Com três pontos, o pedido não entra no funil e vai para uma quarentena, onde a dona pode resgatá-lo se o filtro errar.

Contra os vendedores, funcionou. Doze foram parar na quarentena, seis naquele mesmo sábado.

O RobertLow passou porque não tinha nada daquilo. Sem link, sem inglês, sem conversa de vendedor, telefone com onze dígitos. Somava um ponto só, por não ter executado o JavaScript.

E esse era justamente o sinal mais forte. O formulário tem um pequeno script que, no momento do envio, cria um campo com os segundos que a pessoa passou na página. Qualquer navegador executa isso. Um envio sem esse campo é, na prática, um robô. O filtro tinha o sinal certo, com o peso errado.

O que eu fiz, na ordem certa

A ordem importa mais do que a lista. Primeiro para-se o dano, depois fecha-se a porta, depois arruma-se a casa.

1. Desliguei a confirmação automática. Uma linha de configuração, trinta segundos, reversível. Enquanto o resto não estava pronto, cada minuto com ela ligada era mais um e-mail para uma pessoa real. Ela só volta quando o filtro estiver provado e os relatórios de e-mail estiverem limpos.

2. Bloqueei os dois IPs no servidor web. Uma regra de bloqueio que vale para todos os sites do servidor. Isso trava a onda, e não resolve nada sozinho, porque o robô troca de IP. Mas dá tempo para fazer o resto com calma.

3. Reforcei o filtro com o que os logs mostraram. A falta do campo do JavaScript passou de um para três pontos. HTTP/1.0 passou a somar. Data impossível, data no passado e data a mais de três anos passaram a somar. Três ou mais pedidos do mesmo IP no mesmo dia também. Cada sinal fraco sozinho não chega aos três pontos, porque um casal pode errar o ano ou pedir três serviços seguidos. Juntos, derrubam o robô.

Testei antes de publicar, com casos reais. O robô passou a somar entre 10 e 12 pontos. O pedido verdadeiro mais recente da dona somou zero. Um casal estrangeiro escrevendo em inglês somou um. O preço conhecido é uma pessoa real com JavaScript desligado cair na quarentena, o que é raro, e ela é resgatada com um botão.

4. Validei a data no servidor. O ataque revelou um defeito que eu não conhecia. Uma data impossível, como o dia zero, fazia a gravação falhar. O pedido caía num arquivo de emergência, e os e-mails saíam do mesmo jeito. Agora uma data impossível entra sem data, com o texto que a pessoa digitou guardado na mensagem, e nunca mais derruba a gravação.

5. Limitei a taxa de envios. No máximo dois por minuto por IP, com folga de cinco seguidos. Serve contra rajadas. Não trava este robô, que mandava um pedido a cada poucos minutos justamente para ficar abaixo desse tipo de limite. Quem trava o robô lento é o filtro do passo 3.

6. Arrumei a casa. Os pedidos falsos saíram do funil e foram para a quarentena, com o mesmo número, sem apagar nada. Os que tinham caído no arquivo de emergência também. Os lembretes automáticos de "pedido parado há três dias", que iam disparar dezenas de vezes na segunda-feira, deixaram de ter motivo.

7. Procurei as outras portas. Essa é a parte que quase ninguém faz. O site tinha um simulador de preço que também mandava um e-mail para o endereço digitado. O robô ainda não tinha descoberto, mas era a mesma falha esperando a vez. O simulador já tinha um limite, só que por IP, e um robô com vários IPs passa por ele. Ganhou um teto diário para todos juntos e deixou de mandar e-mail para envios em HTTP/1.0.

Procurando essas portas, encontrei mais uma. O arquivo de emergência, onde caem os pedidos quando a base falha, estava dentro da pasta pública do site. Qualquer pessoa que soubesse o nome podia baixá-lo, com nome, telefone e e-mail de quem estivesse lá. Os logs mostraram que ninguém tinha baixado. Fechei na hora.

8. Liguei o Cloudflare Turnstile. É um captcha invisível e gratuito da Cloudflare. A pessoa de verdade quase nunca vê desafio nenhum, e o robô não consegue gerar o código que ele entrega. Ficou nos três formulários do site. No servidor, um envio sem esse código não é rejeitado, vai para a quarentena, para uma pessoa real com bloqueador nunca se perder.

Como ligar o Turnstile no seu site (grátis)

  • Crie uma conta grátis na Cloudflare e abra Turnstile, depois Add widget.
  • Ponha o endereço do seu site em hostnames, escolha o modo Managed e salve. Você recebe uma chave pública (sitekey) e uma chave secreta.
  • No formulário, cole o script da Cloudflare e o bloco com a chave pública, antes do botão de enviar.
  • No servidor, antes de gravar o pedido, confira o código que chega do formulário no endereço de verificação da Cloudflare (siteverify), com a chave secreta. A chave secreta nunca vai para a página.
  • Teste com um envio de verdade pelo celular e com um envio sem o código. O primeiro passa, o segundo tem de ir para a quarentena.
  • Atualize a política de privacidade do site, que passa a usar um serviço da Cloudflare.
  • O resultado

    • Antes da correção, o robô mandou cerca de 80 pedidos falsos em três dias, e cada um disparou uma confirmação para uma pessoa real.
    • O último envio dele entrou 15 segundos antes de a confirmação ficar desligada.
    • Depois do bloqueio, o mesmo robô tentou de novo 124 vezes. Todas foram recusadas pelo servidor. Nenhum pedido falso novo entrou.
    • No provedor de e-mail, as confirmações enviadas às vítimas não geraram nenhuma reclamação de spam até agora. Reclamações podem chegar dias depois, por isso eu continuo olhando.
    • A confirmação automática só volta a ser ligada com o filtro e o Turnstile provados, e com travas.

    Checklist para o seu formulário

    Se você tem um site com formulário de contato ou de orçamento, confira isto hoje.

    • O seu site manda algum e-mail automático para o endereço que o visitante digita? Se sim, ele só pode sair depois do filtro de spam, nunca antes.
    • O formulário tem um campo escondido que só um robô preenche? É o mais simples, e os robôs melhores já passam por ele.
    • O formulário tem algum sinal que exige JavaScript, como um campo criado no momento do envio? E esse sinal pesa o suficiente para derrubar o envio sozinho?
    • O servidor confere os dados de novo, mesmo que a página já confira? Datas, telefones, números. O robô não usa a sua página, ele fala direto com o servidor.
    • Os pedidos suspeitos vão para uma quarentena que alguém revê, ou são apagados sem ninguém ver? Apagar esconde os erros do filtro.
    • Existe um limite de envios por IP e um teto diário de e-mails automáticos, somando todos os IPs?
    • Os arquivos de emergência, logs e cópias de segurança estão fora da pasta pública do site?
    • Alguém recebe os relatórios diários de e-mail do seu domínio e sabe onde conferir devoluções e reclamações de spam?

    Três erros que eu vi, e um que eu cometi

    Achar que bloquear o IP resolve. Resolve até o robô mudar de servidor, o que ele faz em minutos. O bloqueio compra tempo, e o tempo tem de ser usado para o filtro.

    Achar que um captcha é o primeiro passo. Um captcha invisível, como o Cloudflare Turnstile, é uma boa camada seguinte, e foi o que ligamos no mesmo dia, de graça. Mas se a confirmação automática continuasse ligada, bastava um robô melhor passar o captcha para o problema voltar igual. Primeiro você tira o megafone da mão do robô.

    Tratar "o pedido nunca se perde" como "o e-mail sai sempre". A regra certa era a primeira. Quando a gravação falha, faz sentido avisar a dona. Mandar a confirmação para o endereço de um desconhecido, não.

    O meu. Durante a correção, fiz cópias de segurança dos arquivos que ia mudar, com um ponto no início do nome, dentro da pasta do site. Ficaram acessíveis pela internet durante uns dez minutos, até eu perceber ao conferir o arquivo de emergência. Não tinham senha nenhuma, mostravam o código do filtro. Mudei as cópias para fora da pasta pública e o servidor passou a recusar qualquer arquivo com ponto no início do nome. Regra que ficou, cópia de segurança nunca dentro da pasta do site.

    O que fica disto

    O robô não foi esperto. Era um script que visitava a página, esperava menos de um segundo e mandava o formulário, dia e noite. O que o tornou perigoso foi uma conveniência nossa, o e-mail simpático de confirmação.

    Toda automação que fala com o mundo em seu nome precisa de um porteiro antes. Não depois. O formulário, o chatbot, o e-mail automático, o WhatsApp que responde sozinho. Se um desconhecido consegue fazer o seu sistema escrever para um terceiro, alguém vai descobrir.

    Hoje o formulário está protegido, o funil está limpo e o robô continua batendo na porta sem entrar. Se você quiser que eu olhe para o formulário do seu site com esse checklist, fale comigo.

    Perguntas frequentes

    Isso foi um ataque hacker?

    Foi um ataque, mas não uma invasão. Ninguém entrou no servidor nem roubou dados. Um robô usou o formulário público do site, como um visitante faria, milhares de vezes, para fazer o site mandar e-mails para pessoas reais. É o tipo de ataque automatizado mais comum contra sites de pequenas empresas, e dá para travar sem custo com um filtro no servidor e um captcha invisível como o Cloudflare Turnstile.

    Por que um robô envia pedidos de orçamento falsos?

    Na maioria das vezes, para testar se o formulário aceita envios automáticos e se manda algum e-mail para o endereço digitado. Um formulário que responde por e-mail para qualquer endereço vira uma forma gratuita de mandar mensagens assinadas por um domínio legítimo. Os e-mails usados costumam ser de pessoas reais, tirados de listas vazadas.

    Um captcha resolve spam em formulário?

    Ajuda, mas não é o primeiro passo. O primeiro é garantir que o formulário não manda nada automático para o endereço que o visitante digita. Depois vêm os sinais baratos, como um campo criado por JavaScript no envio e a validação dos dados no servidor. Um captcha invisível, como o Cloudflare Turnstile, é a camada seguinte, e é grátis.

    Bloquear o IP do robô resolve?

    Trava a onda do momento, não resolve. No caso deste artigo, o mesmo robô tinha usado um IP diferente dois dias antes. Quem protege de verdade é o filtro que olha para o comportamento do envio.