Validar assinaturas de webhook
O segredo do webhook é exibido uma única vez quando um diretor da imobiliária cria ou regenera a configuração. Armazene-o em um gerenciador de segredos.
Para cada requisição:
- Leia
Webhook-Timestampe rejeite horários fora da tolerância definida por sua integração. - Preserve o corpo da requisição como bytes brutos.
- Calcule o HMAC-SHA256 de
<timestamp>.<corpo bruto>usando o segredo do webhook. - Adicione
v1=antes do resumo hexadecimal em letras minúsculas. - Compare o resultado com
Webhook-Signatureem tempo constante.
Node.js
Seção intitulada “Node.js”import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWebhookSignature({ rawBody, timestamp, signature, secret }) { const expected = `v1=${createHmac('sha256', secret) .update(timestamp) .update('.') .update(rawBody) .digest('hex')}`; const received = Buffer.from(signature, 'utf8'); const calculated = Buffer.from(expected, 'utf8'); return received.length === calculated.length && timingSafeEqual(received, calculated);}var mac = Mac.getInstance("HmacSHA256");mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));mac.update(timestamp.getBytes(StandardCharsets.UTF_8));mac.update((byte) '.');var digest = mac.doFinal(rawBody);var expected = "v1=" + HexFormat.of().formatHex(digest);var valid = MessageDigest.isEqual( expected.getBytes(StandardCharsets.UTF_8), signature.getBytes(StandardCharsets.UTF_8));Não interprete e serialize novamente o JSON antes da validação. Diferenças de espaços, caracteres de escape ou ordem das propriedades alteram a assinatura.
