diff --git a/docs/details/webhooks.mdx b/docs/details/webhooks.mdx index e7cc180856fb7170e12623885903abeec9e044d0..41fdb1bce4f8072162b467570634a06ae5d44814 100644 --- a/docs/details/webhooks.mdx +++ b/docs/details/webhooks.mdx @@ -1,55 +1,59 @@ --- -title: Sicherheitsvorgaben für Webhooks +title: Sicherheitsvorgaben für Callbacks --- 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). + +Der FIT-Connect Zustelldienst informiert sendende und empfangende Systeme (API-Clients) aktiv über [neue Einreichungen](../getting-started/receiving/query.mdx) oder [Statusupdates](../getting-started/sending/query-status.mdx). +Hierzu werden HTTP-Callbacks genutzt, die auch als [Webhooks](https://de.wikipedia.org/wiki/WebHooks) bezeichnet werden. 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. +Im Folgenden verwenden wir die Begriffe *Callback* und *Webhook* synonym. + ## 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 +https://fachverfahren.beispielstadt.example.org/callbacks/fit-connect ``` Die Callback-URL **MUSS** über HTTPS erreichbar sein. -Der Zustelldienst wird Webhooks nur über eine via HTTPS verschlüsselte Verbindung auslösen. +Der Zustelldienst wird Callbacks nur über eine via HTTPS verschlüsselte Verbindung auslösen. -## Konfiguration von Webhooks -TODO: Aushandlung des Webhook Secret via API +## Konfiguration von Callbacks +TODO: Aushandlung des Callback 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. +## Prüfung von Callbacks +API-Clients, die Callbacks empfangen, **MÜSSEN** zwingend sicherstellen, dass ausgelöste Callbacks von einem vertrauenswürdigen Zustelldienst stammen. +Hierzu enthalten Callbacks 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 *Callback Secret* genannt, wird bei der Konfiguration eines Callbacks festgelegt **DARF NICHT** an Dritte weitergegeben werden. -Der Message Authentication Code wird im HTTP-Header `webhook-authentication` übertragen. +Der Message Authentication Code wird im HTTP-Header `callback-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. +Dieser Timestamp wird im HTTP-Header `callback-timestamp` übertragen. -Durch die Prüfung des Message Authentication Code können API-Clients die Herkunft und Integrität eines Webhooks verifizieren. +Durch die Prüfung des Message Authentication Code können API-Clients die Herkunft und Integrität eines Callbacks verifizieren. -Das folgende Beispiel zeigt die Verwendung der HTTP-Header `webhook-authentication` und `webhook-timestamp`: +Das folgende Beispiel zeigt die Verwendung der HTTP-Header `callback-authentication` und `callback-timestamp`: ```http -POST /webhooks/fit-connect -webhook-authentication: HMAC(key={shared-secret}, message={timestamp}.{http-body}) -webhook-timestamp: 1631283222821 +POST /callbacks/fit-connect +callback-authentication: HMAC(key={shared-secret}, message={timestamp}.{http-body}) +callback-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). +Der HMAC wird gebildet aus dem im HTTP-Header `callback-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. +Um den Message Authentication Code (HMAC) zu verifizieren, bildet der API-Client mit Hilfe des *Callback Secret* den HMAC nach und vergleicht diesen mit dem im HTTP-Header `callback-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. +- Das Callback Secret **MUSS** in API-Clients konfigurierbar sein und **DARF NICHT** fest im Quellcode eines API-Clients einprogrammiert sein. +- Callbacks mit ungültigem Message Authentication Code **MÜSSEN** von API-Clients irgnoriert werden.