Zum Inhalt springen

Wie prüfe ich die Webhook-Signatur?

Ab Tarif Elite

Jede Zustellung trägt den Header X-Webhook-Signature: sha256=<hexdigest>. Der Wert ist ein HMAC-SHA256 über den rohen Request-Body, geschlüsselt mit dem Signatur-Secret deines Webhooks. Zum Prüfen berechnest du denselben HMAC auf deiner Seite und vergleichst zeitkonstant. Stimmen die Werte nicht überein: Anfrage verwerfen. Sie stammt nicht (unverändert) von Notory.

Wichtig: Der HMAC wird über die unveränderten Body-Bytes gebildet. Verifiziere also vor dem JSON-Parsen bzw. auf dem Roh-Body: Ein re-serialisiertes JSON hat fast nie dieselben Bytes.

  1. Secret hinterlegen. Lege das beim Erstellen angezeigte Secret im Secret-Store deines Empfänger-Systems ab (Umgebungsvariable, Vault, nicht im Code).

  2. Prüf-Logik einbauen. Implementiere im Endpunkt: rohen Body lesen → HMAC-SHA256 mit dem Secret berechnen → mit dem Header X-Webhook-Signature (nach dem Präfix sha256=) zeitkonstant vergleichen → bei Abweichung mit 401 ablehnen.

  3. Mit „Test senden” verifizieren. Löse in Notory eine Testzustellung aus (ping-Ereignis). Erst wenn dein Endpunkt die Signatur akzeptiert und 2xx liefert, nimmst du produktive Ereignisse an.

  • Signatur-Bildung in Notory. Vor dem Versand serialisiert Notory den Umschlag {"event": …, "data": …} zu JSON und berechnet HMAC_SHA256(secret, body) als Hex-Digest. Der Header lautet exakt X-Webhook-Signature: sha256=<hexdigest>; zusätzlich nennt X-Webhook-Event den Ereignisnamen.
  • Was die Prüfung garantiert: Authentizität (nur wer das Secret kennt, kann gültig signieren) und Integrität (jede Änderung am Body invalidiert die Signatur). Sie ersetzt kein TLS: Nutze HTTPS-Endpunkte, damit auch Vertraulichkeit gilt.
  • Kein Zeitstempel im Umschlag. Der Payload enthält keinen signierten Zeitstempel oder eine Zustell-ID. Einen strengen Replay-Schutz musst du bei Bedarf fachlich lösen (z. B. Idempotenz über die id des Objekts in data).
  • Zeitkonstant vergleichen. Nutze hmac.compare_digest / crypto.timingSafeEqual statt ==, um Timing-Angriffe auf den Vergleich auszuschließen.
  • Secret-Rotation. Es gibt keinen Endpunkt zum Neuausstellen des Secrets: Webhook neu anlegen, Empfänger auf das neue Secret umstellen, alten Webhook löschen.