Verificar a assinatura
Toda entrega chega com o header:
Code
t— o instante do envio, em segundos (epoch)v1—HMAC-SHA256em hexadecimal
O que é assinado
Code
O t do header, um ponto, e o corpo exatamente como chegou.
Use o corpo CRU, nunca o objeto reserializado
Se você fizer JSON.parse e depois JSON.stringify para conferir, os bytes mudam — espaçamento,
ordem de chaves, escape de acento — e a assinatura nunca vai bater, mesmo estando correta.
Muitos frameworks já consumiram o corpo quando seu código roda. Configure o seu para guardar o
corpo cru (em Express, a opção verify do express.json()).
O procedimento
Code
Se não conferir, responda com erro e descarte. Uma assinatura que não bate significa que o corpo não veio de nós, ou não veio íntegro.
Dois detalhes que quebram integrações
Aceite mais de um v1. Durante uma rotação de segredo vão duas assinaturas no mesmo header, a
nova primeiro. Um código que leia só a primeira ocorrência funciona — mas um que valide apenas
contra o segredo atual derruba toda entrega da janela de 24 horas.
Compare em tempo constante. Não use ===.
Sobre repetição de mensagem (replay)
O t entra no material assinado, então ninguém pode reaproveitar um corpo assinado alterando o
horário: mudar o t invalida a assinatura.
Mas nós não impomos janela nenhuma — a decisão é sua
O servidor não rejeita uma entrega por causa do t. Se você quer proteção contra reenvio de
uma mensagem capturada, é o seu código que precisa comparar o t com o horário atual e recusar
o que estiver velho demais.
Recomendamos 5 minutos de tolerância. É recomendação, não comportamento do servidor.
O t é carimbado no instante do envio, então em condições normais ele chega com poucos segundos
de idade. A folga de 5 minutos existe para atraso de rede e diferença de relógio entre servidores,
não para o caminho normal.
Verificação em ordem
- Ler o corpo cru
- Conferir a assinatura (aceitando múltiplos
v1, em tempo constante) - Só então interpretar o JSON
- Responder 2xx rápido — e processar depois, se for demorado
O passo 4 importa: o tempo limite de cada entrega é 10 segundos.