diff --git a/docs/details/webhooks.mdx b/docs/details/webhooks.mdx new file mode 100644 index 0000000000000000000000000000000000000000..e7cc180856fb7170e12623885903abeec9e044d0 --- /dev/null +++ b/docs/details/webhooks.mdx @@ -0,0 +1,55 @@ +--- +title: Sicherheitsvorgaben für Webhooks +--- + +import ApiLink from '@site/src/components/ApiLink' + +Der Zustelldienst informiert sendende und empfangende Systeme (API-Clients) via [Webhooks](https://de.wikipedia.org/wiki/WebHooks) über [neue Einreichungen](../getting-started/receiving/query.mdx) oder [Statusupdates](../getting-started/sending/query-status.mdx). +Webhooks ermöglichen es, API-Clients aktiv über diese Ereignisse zu informieren ohne dass eine regelmäßige Abfrage ([Polling](https://de.wikipedia.org/wiki/Polling_(Informatik))) nötig wäre. +Technisch werden Webhooks als HTTP-POST-Request realisiert. + +## Callback-URL +Hierzu stellen API-Clients einen HTTP-Endpunkt bereit, an den der Zustelldienst einen HTTP-POST-Request mit übermitteln kann. + +Die URL dieses HTTP-Endpunkts (`callbackUrl`) wird von dem an FIT-Connect angebundenen System festgelegt. +Eine solche Callback-URL kann z.B. wie folgt aussehen: +``` +https://fachverfahren.beispielstadt.example.org/webhooks/fit-connect +``` + +Die Callback-URL **MUSS** über HTTPS erreichbar sein. +Der Zustelldienst wird Webhooks nur über eine via HTTPS verschlüsselte Verbindung auslösen. + +## Konfiguration von Webhooks +TODO: Aushandlung des Webhook Secret via API + +## Prüfung von Webhooks +API-Clients, die Webhooks empfangen, **MÜSSEN** zwingend sicherstellen, dass ausgelöste Webhooks von einem vertrauenswürdigen Zustelldienst stammen. +Hierzu enthalten Webhooks einen Message Authentication Code (HMAC) gemäß [RFC 2104](https://datatracker.ietf.org/doc/html/rfc2104) auf Basis eines geheimen symmetrischen Schlüssels. +Der geheime Schlüssel, im Folgenden *Webhook Secret* genannt, wird bei der Konfiguration eines Webhooks festgelegt **DARF NICHT** an Dritte weitergegeben werden. + +Der Message Authentication Code wird im HTTP-Header `webhook-authentication` übertragen. +Um [Replay-Angriffe](https://de.wikipedia.org/wiki/Replay-Angriff) zu vermeiden, enthält der Message Authentication Code einen aktuellen Timestamp. +Dieser Timestamp wird im HTTP-Header `webhook-timestamp` übertragen. + +Durch die Prüfung des Message Authentication Code können API-Clients die Herkunft und Integrität eines Webhooks verifizieren. + +Das folgende Beispiel zeigt die Verwendung der HTTP-Header `webhook-authentication` und `webhook-timestamp`: +```http +POST /webhooks/fit-connect +webhook-authentication: HMAC(key={shared-secret}, message={timestamp}.{http-body}) +webhook-timestamp: 1631283222821 + +{"submissionIds":["..."]} +``` + +Der HMAC wird gebildet aus dem im HTTP-Header `webhook-timestamp` übertragenen Zeitstempel und dem im HTTP-Body übertragenen Payload, getrennt durch das Zeichen `.` (Punkt). + +Um den Message Authentication Code (HMAC) zu verifizieren, bildet der API-Client mit Hilfe des *Webhook Secret* den HMAC nach und vergleicht diesen mit dem im HTTP-Header `webhook-authentication` übertragenen HMAC. + +Dabei sind die folgenden Implementierungshinweise zwingend zu beachten: +- Bei der Erzeugung des HMAC *MUSS* der Hash-Algorithmus `SHA-512` verwendet werden. +- Es *MUSS* geprüft werden, dass der angegebene Zeitstempel nicht älter als **5 Minuten** ist. +- Beim Vergleich des übertragenen HMAC und des vom API-Client gebildeteten HMAC *MUSS* ein zeitlich konstanter Zeichenfolgenvergleich (*constant time string comparison*) verwendet werden. In Python kann dies über die Verwendung der Methode `hmac.compare_digest` erreicht werden. +- Das Webhook Secret **MUSS** in API-Clients konfigurierbar sein und **DARF NICHT** fest im Quellcode eines API-Clients einprogrammiert sein. +- Webhooks mit ungültigem Message Authentication Code **MÜSSEN** von API-Clients irgnoriert werden.