Início › Guias › Segurança em automação e webhooks
Guia

Como validar assinatura HMAC em webhook no n8n (e evitar requisição falsificada)

Atualizado em 2026-10-13 · por Redação Automação Hoje
Profissional validando assinatura HMAC em webhook no n8n para bloquear requisições falsas
Resposta rápida: Para validar assinatura HMAC em um webhook no n8n, você precisa recalcular a assinatura no fluxo usando o mesmo secret do provedor (HMAC + hash, como SHA-256), comparar com o header recebido e rejeitar se não bater. Para ficar robusto, valide também timestamp/nonce, limite janela de tempo e use comparação em tempo constante para reduzir risco de bypass.
· espaço publicitário ·
  1. 1) Descubra o “contrato” do provedor (o que é assinado)

    Antes de abrir o n8n, confirme quais campos entram no HMAC: corpo bruto (raw body) ou JSON normalizado, caminho/URL, query string, timestamp e qual header carrega a assinatura. Provedores variam muito: alguns assinam "timestamp + '.' + body", outros assinam só o body. Se você não tiver a documentação, peça um exemplo real de request e headers e trate como contrato.

  2. 2) Capture o request no Webhook node (sem “transformar” cedo demais)

    Crie um Webhook node e garanta que você consiga acessar: headers, query e o body. O ponto crítico: muitos HMACs usam o corpo exatamente como chegou (bytes). Se você parseia e re-stringifica, a assinatura pode não bater por causa de espaços, ordem de campos ou encoding. Quando o provedor assina o raw body, tente preservar o conteúdo original (ou use a opção/mecanismo disponível no seu setup para obter o corpo bruto).

  3. 3) Armazene o secret corretamente (não cole no workflow)

    Guarde o secret fora do fluxo, usando o mecanismo de secrets/variáveis de ambiente do seu ambiente. No workflow, referencie o secret por variável/credencial. Isso reduz vazamento em exportação, logs e prints.

  4. 4) Recalcule a assinatura no n8n (Crypto) com o mesmo algoritmo

    Use um Code node (JavaScript) para calcular o HMAC com o algoritmo exigido (ex.: sha256). Construa exatamente a “string para assinar” do jeito que o provedor define. Atenção a detalhes chatos: encoding (utf8), base64 vs hex, prefixos no header (ex.: "sha256=") e presença de quebras de linha.

  5. 5) Compare assinatura recebida vs calculada (sem abrir brecha)

    Compare os valores após normalizar formato (remover prefixos, padronizar maiúsculas/minúsculas quando aplicável). Evite comparação ingênua se você estiver num cenário sensível: idealmente use comparação de tempo constante (quando disponível). Na prática do n8n, o mínimo é: comparar strings já normalizadas e falhar fechado (se qualquer coisa estiver ausente, negar).

  6. 6) Valide timestamp/nonce para bloquear replay attack

    Se o provedor envia timestamp, rejeite requests fora de uma janela curta (por exemplo, alguns minutos). Se houver nonce/ID do evento, registre-o (em Redis/DB) e recuse repetidos por um período. Isso evita replays mesmo com assinatura válida.

  7. 7) Responda rápido e com status correto

    Se a assinatura falhar, responda 401/403 imediatamente. Se passar, prossiga e retorne 200/202 conforme o esperado. Se o processamento for pesado, prefira enfileirar/assíncrono para não estourar timeout do provedor.

O que é assinatura HMAC em webhook (e por que dá trabalho no n8n)

Assinatura HMAC é um jeito de provar que o request veio de quem diz que veio: o provedor calcula um código (hash autenticado) usando um secret compartilhado e manda esse valor num header. Você recalcula no seu lado e compara.

Na prática, o “trabalho” aparece nos detalhes: qual parte do request entra na assinatura (raw body? JSON?), qual encoding, qual algoritmo e como lidar com replay (alguém reenvia o mesmo request). É aqui que automações quebram — ou, pior, passam falsos positivos.

Exemplo de lógica (genérica) para HMAC SHA-256 no Code node

Abaixo vai um exemplo conceitual. Você precisa adaptar para o seu provedor (string para assinar, header e formato). Use como esqueleto mental, não como “copiar e colar sem ler”.

  • Leia assinatura do header: ex. x-signature (ou equivalente).
  • Leia timestamp: ex. x-timestamp (se existir).
  • Monte a mensagem: ex. `${timestamp}.${rawBody}` (exemplo comum, mas não universal).
  • Calcule HMAC SHA-256 com o secret.
  • Normalize formatos (hex/base64, prefixos) e compare.
  • Se falhar, finalize o fluxo retornando 401/403.

Checklist rápido de debug quando “não bate a assinatura”

Quando a assinatura não confere, quase sempre é por causa de string diferente do lado do provedor. Antes de culpar o n8n, passe por este checklist.

SintomaCausa provávelComo testar/arrumar
Assinatura nunca confere, mesmo com secret certoVocê está assinando JSON reformatado, mas o provedor assinou raw bodyCompare o body bruto capturado com o que você usou para calcular; evite parse/restringify antes do HMAC
Confere às vezes, falha em payloads específicosDiferença de encoding/escape ou campos com caracteres especiaisForce UTF-8 e valide se quebras de linha e barras estão idênticas ao original
Assinatura confere, mas eventos duplicamFalta validação de timestamp/nonce (replay)Implemente janela de tempo e dedupe por event-id/nonce em armazenamento
Confere localmente, falha em produçãoSecrets divergentes entre ambientes ou header removido por proxyValide variável de ambiente no runtime e confira se reverse proxy encaminha headers

Boas práticas que evitam dor de cabeça (e incidente)

Falhar fechado: se faltar assinatura, timestamp ou secret, trate como inválido.

Não logue o secret nem a assinatura completa em texto puro; se precisar, masque (ex.: últimos 6 caracteres).

Proteja o endpoint: se fizer sentido, restrinja por IP/ASN do provedor (sem confiar só nisso).

Separe validação de autenticação do resto do fluxo: valide primeiro, processe depois.

Se o webhook dispara processos longos, enfileire ou desacople para reduzir timeout e retries agressivos do provedor.

Perguntas frequentes

Preciso de HMAC se meu webhook já está em HTTPS?
Sim. HTTPS protege o transporte (interceptação no caminho), mas não prova que o emissor é legítimo nem impede alguém de chamar seu endpoint diretamente. O HMAC adiciona autenticidade com base em um secret.
Qual é a diferença entre comparar assinatura em hex e em base64?
É só representação do mesmo resultado. Alguns provedores enviam o HMAC em hex (0-9a-f), outros em base64. Se você calcular em um formato e comparar com outro, vai falhar. Normalize: ou converta seu cálculo para o formato do header, ou decodifique e compare bytes.
Como evitar replay attack no webhook validado por HMAC?
Valide timestamp com janela curta e recuse requests antigos. Se houver event-id/nonce, registre por um período e recuse repetidos. HMAC sozinho não impede replay: ele só prova que o request é “autêntico”, não que é “novo”.
O que fazer quando o provedor assina o body “cru”, mas o n8n não me entrega o raw body igual?
Você tem três caminhos: (1) ajustar seu gateway/proxy para repassar o body e headers sem alterações e capturar o raw body; (2) usar um endpoint intermediário (ex.: função/serviço leve) que valide e repasse para o n8n; (3) negociar com o provedor um modo de assinatura que use campos canônicos (menos comum). O melhor depende do seu stack e do nível de risco.

Leia também