Início › Guias › seguranca-webhooks-automacao
Guia

Como evitar replay attack em webhooks: timestamp, nonce e idempotência (na prática)

Atualizado em 2026-10-14 · por Redação Automação Hoje
Como evitar replay attack em webhooks com timestamp, nonce e idempotência
Resposta rápida: Replay attack em webhook é quando alguém reaproveita uma requisição válida (assinada) para disparar a automação de novo. Para evitar, combine: HTTPS, assinatura (HMAC), validação de timestamp com janela curta, nonce (uso único) e idempotência no processamento. Assim, mesmo que a requisição vaze, ela expira ou vira “duplicada” e não causa efeitos.
· espaço publicitário ·
Em resumo
  • 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. 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. 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. 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. 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. 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. 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écnicaO que resolveO que não resolveOnde costuma falhar
Timestamp + janelaReplay fora do período aceito; reduz risco de replays tardiosReplay dentro da janela; duplicatas por retries legítimosRelógio do servidor fora de sincronia; janela grande demais
Nonce / event_id (uso único)Replay dentro da janela; repetição do mesmo eventoEventos sem ID confiável; ataques com IDs diferentesArmazenamento do nonce sem TTL; perda de cache e reprocesso
Idempotência no efeitoDuplicatas por qualquer motivo (ataque ou falha); garante “no máximo uma vez” por efeitoNão impede consumo repetido; só impede efeito repetidoChave 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?
Sim, na maioria dos casos. HMAC confirma autenticidade do emissor, mas não impede que a mesma requisição assinada seja reenviada. Timestamp reduz a janela de exploração e ajuda a identificar atrasos anormais.
Qual deve ser a janela de tempo (timestamp tolerance)?
Depende do seu cenário de latência e retries. Se você tem filas, provedores que reentregam e internet instável, uma janela curta demais vai gerar falsos negativos. O ideal é medir atrasos típicos e escolher uma janela que cubra o normal sem ficar “larga” a ponto de facilitar replay.
O que eu uso como nonce/event_id se o provedor não envia um ID único?
Você pode criar um identificador derivado (por exemplo, hash do corpo normalizado + origem + timestamp arredondado), mas isso exige cuidado com campos que mudam a cada envio. Quando não há ID confiável, a estratégia mais robusta costuma ser idempotência no efeito (por entidade de negócio) em vez de depender só de nonce.
Posso responder 200 OK para webhooks duplicados?
Em geral, sim — e costuma ser o mais seguro para evitar reentregas automáticas do provedor. Você registra internamente como duplicado e não executa o efeito. Só evite 2xx se o contrato do provedor exigir erro para reprocessar corretamente (caso menos comum).

Leia também