- Assinatura sozinha não impede replay: ela prova autenticidade, não “unicidade”
- Timestamp + janela de aceitação reduz replays fora de tempo
- Nonce (ou event_id) com armazenamento temporário bloqueia replays dentro da janela
- Idempotência garante que efeitos (pedido, cobrança, mensagem) não se repitam
- Logs e métricas ajudam a detectar picos de replays e tentativas automatizadas
1) Garanta o básico: HTTPS e endpoint dedicado
Use HTTPS de ponta a ponta e evite expor o webhook “cru” em IP/porta direta. Prefira domínio com reverse proxy/tunnel bem configurado, e mantenha um endpoint por integração (não um único endpoint “faz tudo”). Isso facilita regras de segurança e rotação de segredos.
2) Valide assinatura (HMAC ou assinatura do provedor)
Valide a assinatura do webhook antes de qualquer ação. A regra editorial aqui é simples: se não passou na assinatura, não entra no fluxo de negócio. Em ferramentas no-code, faça essa validação no primeiro bloco (ou em um workflow de “gateway”) e só então encaminhe para o resto.
3) Exija timestamp e aplique uma janela curta
Peça que o provedor envie um timestamp (ou use o cabeçalho padrão dele) e recuse eventos fora de uma janela de tolerância. O tamanho dessa janela depende do seu cenário (atrasos normais, filas, internet), então trate como decisão de arquitetura: quanto maior a janela, maior a superfície para replay.
4) Use nonce/event_id e bloqueie uso repetido
Nonce (ou event_id) é um identificador único por evento. Armazene-o por um período curto (cache/DB) e rejeite se aparecer de novo. Isso bloqueia replays mesmo dentro da janela do timestamp. Se o provedor não mandar um ID, você pode derivar um (hash do body + timestamp + origem), com cuidado para não colidir.
5) Torne o processamento idempotente (mesmo se passar tudo acima)
Idempotência é a última linha de defesa: mesmo que a mesma mensagem chegue duas vezes, o efeito final não se duplica. Exemplos: criar pedido “se não existir”, enviar WhatsApp “se ainda não foi enviado para este ticket”, emitir nota “se status atual permitir”. Guarde uma idempotency key ligada ao efeito (por exemplo: pedido_id + ação).
6) Faça logging e resposta correta para evitar reentrega infinita
Provedores costumam reenviar webhooks quando recebem erro. Se você detectar replay/duplicidade, responda com sucesso (2xx) quando apropriado e registre o motivo internamente. Se responder 4xx/5xx para duplicatas, você pode induzir o provedor a tentar de novo e piorar a tempestade.
O que é replay attack (e por que acontece em automações)
Replay attack é a reutilização de uma requisição legítima para repetir um efeito: cobrar de novo, criar duplicado no CRM, disparar mensagem duplicada, etc.
Ele acontece por ataque (captura de tráfego, vazamento de logs, credenciais expostas) e também por “quase-acidente”: retries do provedor, filas atrasadas, timeouts, ou dois workers consumindo o mesmo evento.
Assinatura não basta: autenticidade ≠ unicidade
HMAC/assinatura responde à pergunta: “isso veio mesmo de quem diz que veio?”.
Replay attack responde outra: “essa mesma requisição está sendo reaproveitada?”. Se alguém capturar uma chamada assinada, ela continua assinada quando for reenviada. Por isso timestamp/nonce/idempotência entram no pacote.
Checklist rápido: o que validar no webhook (ordem que reduz custo)
A ordem importa: validações baratas primeiro. Em automação no-code, isso também evita gastar operações/execuções com payloads inválidos.
- Rejeitar se não for HTTPS/endpoint esperado (por proxy/regras de rota)
- Validar assinatura (HMAC/assinatura do provedor)
- Validar timestamp dentro da janela aceita
- Checar nonce/event_id (já visto?)
- Checar idempotência no efeito de negócio (já executei esta ação?)
Tabela prática: timestamp vs nonce vs idempotência (quando usar)
| Técnica | O que resolve | O que não resolve | Onde costuma falhar |
|---|---|---|---|
| Timestamp + janela | Replay fora do período aceito; reduz risco de replays tardios | Replay dentro da janela; duplicatas por retries legítimos | Relógio do servidor fora de sincronia; janela grande demais |
| Nonce / event_id (uso único) | Replay dentro da janela; repetição do mesmo evento | Eventos sem ID confiável; ataques com IDs diferentes | Armazenamento do nonce sem TTL; perda de cache e reprocesso |
| Idempotência no efeito | Duplicatas por qualquer motivo (ataque ou falha); garante “no máximo uma vez” por efeito | Não impede consumo repetido; só impede efeito repetido | Chave mal definida (muito ampla ou muito específica) e criação de falsos positivos/negativos |
Decisões que você precisa tomar (sem glamour, mas que definem o resultado)
Qual é a sua “unidade de verdade”: event_id do provedor, ID interno, ou combinação de campos? Isso define sua idempotency key.
Onde armazenar nonces/idempotency keys: banco (mais durável) ou cache (mais rápido). Sem o seu contexto não dá para cravar a escolha; o critério é: qual o impacto se o armazenamento cair e você aceitar duplicatas por alguns minutos?
Qual resposta HTTP dar para duplicatas: na maioria dos casos, 2xx é melhor para impedir reentrega em loop, mas depende do contrato do webhook.
Armadilhas comuns que viram incidente em produção
A regra de ouro: se o seu fluxo tem efeito irreversível (cobrança, emissão, envio), idempotência não é opcional.
- Logar o payload completo com dados sensíveis e depois expor o log (isso vira material de replay)
- Não rotacionar o segredo do HMAC quando há suspeita de vazamento
- Aceitar webhooks sem checar Content-Type/corpo esperado (abre espaço para bypass)
- Fazer a automação “criar e depois verificar” (ordem invertida) em vez de “verificar e depois criar”
- Tratar timeout como falha e repetir efeitos sem idempotência (clássico em integrações com cobrança)
Perguntas frequentes
Se eu já valido HMAC, ainda preciso de timestamp?
Qual deve ser a janela de tempo (timestamp tolerance)?
O que eu uso como nonce/event_id se o provedor não envia um ID único?
Posso responder 200 OK para webhooks duplicados?
Leia também
Como validar assinatura HMAC em webhook no n8n (e evitar requisição falsificada)
Guia prático para validar assinatura HMAC (SHA-256) em webhooks no n8n, rejeitar requests falsificadas e proteger automações com secret e timestamp.
Ler →
Como expor webhooks do n8n com HTTPS (reverse proxy, porta 443 e tunnel) sem virar refém de gambiarra
Guia prático para publicar webhooks do n8n com HTTPS usando Nginx/Caddy/Traefik ou tunnel. Inclui checklist de segurança, variáveis do n8n e erros comuns (URL errada, 404, loop de redirect).
Ler →
Como gerenciar secrets e credenciais no n8n self-hosted (sem vazar dados e sem dor)
Aprenda como organizar, proteger e rotacionar secrets e credenciais no n8n self-hosted: variáveis de ambiente, criptografia, permissões, logs, backups e checklist de produção.
Ler →
Como fazer idempotência em automações com webhook (e parar de duplicar pedidos, notas e leads)
Guia direto para aplicar idempotência em automações com webhook: chaves idempotentes, deduplicação, banco/planilha, retries e boas práticas para n8n/Make/Zapier.
Ler →