Pular para o conteúdo principal

Segurança de Webhook

Cada pedido 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-SignatureDigest hex HMAC-SHA256 de {timestamp}.{body}
X-ConsentForge-TimestampTimestamp Unix (segundos) 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 string de assinatura: {timestamp}.{raw_request_body}
  4. Calcule HMAC-SHA256 da string de assinatura usando o seu segredo webhook
  5. Compare (timing-safe) com a assinatura recebida
  6. Rejeite se o timestamp tiver mais de 5 minutos (proteção contra replay)

Exemplos de código

function verifyConsentForgeWebhook(
string $rawBody,
string $signature,
string $timestamp,
string $secret
): bool {
// Reject if too old (5 minutes)
if (abs(time() - (int)$timestamp) > 300) {
return false;
}

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

return hash_equals($expected, $signature);
}

// Usage in a Laravel controller:
$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

Use X-ConsentForge-Delivery-ID para deduplicar entregas repetidas. Armazene IDs de entrega processados e ignore duplicados.

Rotação do segredo

Para rodar o seu segredo webhook:

  1. Gere um novo segredo no Painel (segredo antigo ainda ativo por 24h)
  2. Atualize o seu servidor para usar o novo segredo
  3. Após 24h, o segredo antigo é invalidado