Przejdź do głównej zawartości

Bezpieczeństwo webhooków

Każde żądanie webhooka od ConsentForge zawiera podpis HMAC-SHA256. Weryfikuj ten podpis przed przetworzeniem ładunku, aby upewnić się, że żądanie jest autentyczne i nie zostało zmanipulowane.

Nagłówki żądania

NagłówekOpis
X-ConsentForge-SignatureSkrót szesnastkowy HMAC-SHA256 z {timestamp}.{body}
X-ConsentForge-TimestampZnacznik czasu Unix (sekundy) wysłania zdarzenia
X-ConsentForge-Delivery-IDUnikalny identyfikator dostarczenia (używaj do idempotencji)

Algorytm weryfikacji

  1. Odczytaj X-ConsentForge-Timestamp z nagłówka żądania
  2. Odczytaj X-ConsentForge-Signature z nagłówka żądania
  3. Zbuduj ciąg podpisywania: {timestamp}.{raw_request_body}
  4. Oblicz HMAC-SHA256 ciągu podpisywania używając swojego sekretu webhooka
  5. Porównaj (bezpieczne czasowo) z otrzymanym podpisem
  6. Odrzuć, jeśli znacznik czasu jest starszy niż 5 minut (ochrona przed powtórzeniem)

Przykłady kodu

function verifyConsentForgeWebhook(
string $rawBody,
string $signature,
string $timestamp,
string $secret
): bool {
// Odrzuć jeśli zbyt stary (5 minut)
if (abs(time() - (int)$timestamp) > 300) {
return false;
}

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

return hash_equals($expected, $signature);
}

// Użycie w kontrolerze 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();

Idempotencja

Użyj X-ConsentForge-Delivery-ID do deduplikacji ponowionych dostarczeń. Przechowuj przetworzone identyfikatory dostarczeń i pomijaj duplikaty.

Rotacja sekretu

Aby zmienić sekret webhooka:

  1. Wygeneruj nowy sekret w Pulpicie (stary sekret nadal aktywny przez 24h)
  2. Zaktualizuj swój serwer, aby używał nowego sekretu
  3. Po 24h stary sekret traci ważność