Skip to main content

Objetivo

Toda requisição de webhook enviada pela NoxPay vem assinada. Validar essa assinatura garante que o webhook:
  • Não foi alterado no caminho (integridade)
  • Foi realmente enviado pela NoxPay (autenticidade)
Valide sempre a assinatura antes de processar o conteúdo do webhook. Nunca confie em um payload não verificado.

Como funciona

A NoxPay assina cada webhook usando um segredo compartilhado (o Webhook Secret). Do seu lado, você reproduz essa mesma assinatura localmente e compara com o valor recebido no header da requisição. Se baterem, o webhook é legítimo.

Webhook Secret

  • Chave secreta exclusiva por integração, gerada pela NoxPay
  • Compartilhada com você de forma segura
  • Nunca é enviada dentro do webhook — só você e a NoxPay a conhecem
Nunca exponha o webhook_secret e nunca reutilize sua API Key como secret. Armazene-o de forma segura (variável de ambiente, cofre de segredos, etc.).

Headers de assinatura

Existem dois métodos de assinatura em uso. Cada um chega em um header diferente:
Ambos os headers podem chegar em integrações — inclusive novas. Por isso, sua implementação deve estar preparada para validar os dois. Priorize o X-Signature (HMAC) e trate o X-Nox-Signature como compatibilidade com o método antigo.

Método atual — HMAC-SHA256

Header de comparação: X-Signature

Fórmula

Onde:
  • webhook_secret → o segredo compartilhado
  • raw_body → o corpo da requisição exatamente como recebido (bytes brutos)
  • encoding → UTF-8

Passo a passo

1

Capture o raw body

Pegue o corpo da requisição exatamente como chegou, sem parsear nem reserializar o JSON.
2

Gere o HMAC-SHA256

Calcule o HMAC usando o webhook_secret como chave e o raw_body como mensagem.
3

Codifique em Base64

Converta o resultado binário do HMAC para uma string Base64.
4

Compare com segurança

Compare com o header X-Signature usando uma função de comparação em tempo constante (para evitar timing attacks).

Exemplos de código


Método legado — SHA256 simples

Header de comparação: X-Nox-Signature
Este é o método legado. Ele ainda pode aparecer em qualquer integração, então mantenha o suporte a ele — mas prefira sempre o X-Signature (HMAC-SHA256) e não use este método como base de novas implementações.

Fórmula

Aqui o segredo é simplesmente concatenado na frente do corpo, e o hash é feito em cima dessa junção.

Exemplos de código

O SHA256 simples é apenas uma função de hash genérica. No método legado, a segurança vem de concatenar o segredo na frente do corpo (SHA256(webhook_secret + raw_body)). O problema é que o SHA256 não foi desenhado para uso como código de autenticação: em certos cenários ele é vulnerável a um length extension attack, onde é possível calcular um novo hash válido sem conhecer o segredo completo.O HMAC-SHA256 foi criado exatamente para esse fim. Ele aplica o hash em duas camadas, misturando a chave de formas diferentes em cada uma. Essa estrutura fecha a brecha do length extension attack e é matematicamente comprovada como segura para autenticação de mensagens — por isso é o padrão de mercado para assinar webhooks.Em resumo: o SHA256 simples é como colar uma senha na frente de um documento e embaralhar tudo junto. O HMAC usa a senha como uma chave que embaralha o conteúdo de um jeito estruturado e testado — muito mais difícil de burlar.

Pontos críticos

Valem para os dois métodos.

1. Use o raw body real (o mais importante)

A assinatura depende dos bytes exatos do corpo. Qualquer alteração quebra a validação, incluindo espaços, quebras de linha, ordem das chaves ou reserialização do JSON.
Webhook signature não valida JSON — valida bytes exatos. Capture o corpo cru antes de qualquer middleware que parseie a requisição (ex.: express.raw() no Express, ou o await request.body() cru no FastAPI).

2. Encoding

Use sempre UTF-8, em todas as etapas.

Debug / Troubleshooting

Se a assinatura não bater, verifique nesta ordem:
  • O raw body não foi alterado (causa nº 1)
  • O método correto está sendo usado (HMAC para X-Signature, SHA256 legado para X-Nox-Signature)
  • O Webhook Secret está correto
  • O encoding é UTF-8
  • O header correto está sendo lido
Em ambiente seguro, logue a assinatura esperada vs a recebida lado a lado. A diferença geralmente aponta direto para a causa.