Pular para o conteúdo principal

Segurança de Webhooks

Cada pedido de webhook do ConsentForge inclui uma assinatura HMAC-SHA256. Verifique esta assinatura antes de processar o payload para garantir que o pedido é genuíno e não foi adulterado.

Cabeçalhos do pedido

CabeçalhoDescrição
X-ConsentForge-SignatureResumo hexadecimal HMAC-SHA256 de {timestamp}.{body}
X-ConsentForge-TimestampTimestamp Unix (segundos) de quando o evento foi enviado
X-ConsentForge-Delivery-IDID único para esta entrega (use para idempotência)

Algoritmo de verificação

  1. Leia X-ConsentForge-Timestamp do cabeçalho do pedido
  2. Leia X-ConsentForge-Signature do cabeçalho do pedido
  3. Construa a cadeia de assinatura: {timestamp}.{raw_request_body}
  4. Calcule o HMAC-SHA256 da cadeia de assinatura utilizando o seu segredo de webhook
  5. Compare (com tempo constante) com a assinatura recebida
  6. Rejeite se o timestamp tiver mais de 5 minutos de antiguidade (protecção contra repetição)

Exemplos de código

function verifyConsentForgeWebhook(
string $rawBody,
string $signature,
string $timestamp,
string $secret
): bool {
// Rejeitar se for demasiado antigo (5 minutos)
if (abs(time() - (int)$timestamp) > 300) {
return false;
}

$signingString = $timestamp . '.' . $rawBody;
$expected = hash_hmac('sha256', $signingString, $secret);

return hash_equals($expected, $signature);
}

// Uso num controlador Laravel:
$rawBody = $request->getContent();
$signature = $request->header('X-ConsentForge-Signature');
$timestamp = $request->header('X-ConsentForge-Timestamp');
$secret = config('services.consentforge.webhook_secret');

if (!verifyConsentForgeWebhook($rawBody, $signature, $timestamp, $secret)) {
return response('Unauthorized', 401);
}

$payload = $request->json()->all();

Idempotência

Utilize X-ConsentForge-Delivery-ID para desduplicar entregas repetidas. Armazene os IDs de entrega processados e salte os duplicados.

Rotação de segredo

Para rodar o seu segredo de webhook:

  1. Gere um novo segredo no Painel (o segredo antigo permanece activo durante 24h)
  2. Actualize o seu servidor para utilizar o novo segredo
  3. Após 24h, o segredo antigo é invalidado