Verificação da assinatura
Toda requisição de webhook chega com:
X-Infi-Timestamp: unix timestamp em segundos.X-Infi-Signature:sha256=<hex>, onde<hex>é o HMAC-SHA256 calculado sobre a concatenação"{timestamp}.{corpo bruto}"usando o segredo do webhook.
Algoritmo
- Capture o corpo bruto da requisição (bytes, antes de qualquer parsing JSON).
- Capture os headers
X-Infi-TimestampeX-Infi-Signature. - Concatene:
payload = "{timestamp}.{rawBody}". - Compute
expected = HMAC-SHA256(WEBHOOK_SECRET, payload)e codifique em hex. - Compare
"sha256=" + expectedcom o cabeçalho recebido em tempo constante.
Use o corpo bruto, não JSON reserializado
A assinatura é sobre os bytes exatos enviados. Reserializar o JSON do seu lado pode mudar ordem de chaves ou espaçamento e quebrar a verificação. Configure seu framework para preservar o body bruto (ex.: em Express use express.raw({ type: 'application/json' })).
Onde obter o `WEBHOOK_SECRET`
O segredo é entregue junto com sua API key, pelo canal seguro combinado com a INFI (e-mail criptografado ou painel). Não exponha em código-fonte público nem em logs — armazene como variável de ambiente.
Mitigação de replay
Recomendado: rejeite webhooks com X-Infi-Timestamp muito antigo (ex.: > 5 minutos). Isso protege contra replay de webhooks legítimos capturados em trânsito.
Exemplos
# Validação shell — geralmente delega para a linguagem da aplicação.
# Conceito:
# payload="${TIMESTAMP}.${RAW_BODY}"
# expected=$(echo -n "$payload" | openssl dgst -sha256 -hmac "$INFI_WEBHOOK_SECRET" | awk '{print $2}')
# [[ "sha256=$expected" == "$X_INFI_SIGNATURE" ]]