Best Practices für die Webhook-Sicherheit
Gints Dreimanis
6. Juli 2022
0 Min. LesezeitWebhooks eignen sich hervorragend, um Informationen zu einzelnen Ereignissen von einem System an ein anderes zu übertragen. Anders als bei Methoden wie HTTP-Polling – bei dem der Client wiederholt Informationen vom Server abfragt – werden Webhooks durch Ereignisse ausgelöst.
Dadurch sind sie einfach und effektiv. Ein Client kann einen Webhook abonnieren, damit dieser bei einem bestimmten Ereignis eine Nachricht an einen Endpunkt sendet.
Da Webhooks häufig Nachrichten an einen öffentlichen Endpunkt im Internet senden, können Sicherheitsprobleme auftreten. Ohne geeignete Sicherheitsmaßnahmen können Angreifer Nachrichten lesen und verändern oder sich sogar vollständig als Sie ausgeben. Deshalb müssen wir alle möglichen Schritte unternehmen, um beim Betrieb eines Webhook-Dienstes das erforderliche Sicherheitsniveau zu erreichen.
In diesem Blogbeitrag stellen wir die effektivsten Maßnahmen vor, mit denen Sie Webhooks schützen und Daten zwischen Anwendungen austauschen können, ohne eine große Angriffsfläche zu schaffen.
8 Best Practices für die Sicherheit bei der Erstellung von Webhooks
Bei der Implementierung eines Webhooks sollten Sie sich am besten nicht auf eine einzelne Sicherheitsmaßnahme verlassen. Stattdessen sollten wir mehrere Ansätze umsetzen, damit unser System sicher bleibt – selbst wenn ein Angreifer einige unserer Sicherheitsmaßnahmen überwindet.
Mindestens sollten wir Verschlüsselung einsetzen, damit Nachrichten an und von Clients vertraulich bleiben, sowie eine gegenseitige Authentifizierung, damit Client und Server sicher sein können, mit wem sie kommunizieren.
Über Webhooks gesendete Daten verschlüsseln
Wir können zwar nicht verhindern, dass Angreifer unsere Nachrichten abfangen, aber wir können verhindern, dass sie deren Inhalt lesen. Eine einfache Möglichkeit, die sichere Kommunikation zu gewährleisten, ist die Verwendung von HTTPS statt HTTP.
HTTPS lässt sich sehr einfach verwenden, und es gibt kaum einen Grund, darauf zu verzichten. HTTPS verschlüsselt alle Daten und erschwert Dritten so den Zugriff darauf erheblich.
Webhooks signieren
Angreifer können im Internet gesendete Nachrichten abfangen und zu ihrem Vorteil verändern. Um unerwünschte Änderungen zu verhindern, sollten wir unsere Nachrichten signieren. Dazu können wir einen Hash-based Message Authentication Code (HMAC) verwenden, der aus einem Hash-Algorithmus und einem geheimen Code oder Schlüssel besteht, den beide Parteien gemeinsam nutzen.
HMAC-Hashes (oder Verschlüsselungen) weisen jeder Nachricht eine bestimmte Hash-Funktion zu. So kann ein Webhook-Empfänger die Authentizität und Integrität einer Nachricht überprüfen, indem er die Nachricht mit dem Hash vergleicht.
Weitere Informationen zum Signieren von Webhooks finden Sie in diesem hilfreichen Twilio-Artikel.
Verbindungen authentifizieren
Webhook-Endpunkte sind häufig öffentlich und für alle im Internet zugänglich. Dadurch entstehen für Webhook-Empfänger mehrere Sicherheitslücken, darunter auch Denial-of-Service-Angriffe. Um dieses Problem zu lösen, sollten Webhook-Empfänger die Herkunft der Nachrichten authentifizieren. Dazu können sie einen Benutzernamen und ein Passwort oder ein Authentifizierungstoken verwenden.
Außerdem empfiehlt es sich, den Empfänger zu authentifizieren, damit die Nachricht am richtigen Ort ankommt.
Nachrichten mit Zeitstempeln versehen
Wir können unsere Nachrichten mit dem Versandzeitpunkt versehen, um Replay-Angriffe zu verhindern. Bei Replay-Angriffen werden Nachrichten weder gelesen noch manipuliert. Stattdessen fangen Angreifer eine legitime, verschlüsselte Nachricht ab und senden sie zu einem günstigen Zeitpunkt erneut.
Wenn wir unsere Nachrichten mit Zeitstempeln versehen, kann der Client sicherstellen, dass die gesendete Nachricht aktuell ist und nicht etwa vor einigen Wochen verschickt wurde. Da unsere Nachrichten außerdem signiert sind, kann der Angreifer den Zeitstempel nicht ändern und die Nachricht auch nicht für einen Replay-Angriff speichern.
Certificate Pinning verwenden
Wenn unser Client eine Verbindung von einem Webserver mit einem vertrauenswürdigen Zertifikat für unsere API erhält, bedeutet das nicht, dass die Website (und das Zertifikat) tatsächlich uns gehört. Ein potenzieller Angreifer kann unsere API kopieren und ein vertrauenswürdiges Zertifikat hinzufügen. Anschließend kann er die legitime Nachricht abfangen und stattdessen eine eigene senden.
Eine Möglichkeit, dieses Problem zu lösen, ist Certificate Pinning. Wenn das Ereignis jedes Mal vom selben Server kommt, kann der Client das Serverzertifikat im Code hinterlegen. Beim Certificate Pinning wird das Zertifikat oder sein Hash (Fingerabdruck) fest im Code der App hinterlegt und bei jedem Verbindungsaufbau mit dem bereitgestellten Zertifikat verglichen.
Bei dieser Technik ist jedoch Vorsicht geboten, da sie auf fest codierten Parametern beruht. Ändert sich ein Zertifikat oder wird es widerrufen, kann der Client das Zertifikat möglicherweise nicht schnell genug aktualisieren.
Ein Beispiel für Certificate Pinning finden Sie in dieser Dokumentation von Mozilla.
Webhooks nicht für sensible Daten verwenden
Auch wenn Webhooks abgesichert sind, eignen sie sich nicht für sensible Daten wie Passwörter oder Kreditkarteninformationen. Im Allgemeinen dienen Webhooks dazu, über Ereignisse zu informieren. Wenn Sie sensible Daten in über Webhooks gesendete Nachrichten aufnehmen, sollten Sie Ihren Anwendungsfall überdenken.
Alle ausgehenden Webhook-Nachrichten protokollieren
Webhook-Nachrichten lassen sich mit einer internen oder einer Drittanbieterlösung protokollieren. Protokolle halten jede gesendete Nachricht fest und sind bei Audits hilfreich. Außerdem können wir im Falle eines Sicherheitsvorfalls alle gesendeten Nachrichten und initiierten Verbindungen nachvollziehen. Die Überwachung von Protokollen kann auch dabei helfen, verdächtiges Verhalten – etwa fehlgeschlagene Zustellversuche – zu erkennen, bevor es zu einem Sicherheitsvorfall kommt.
Das Protokollieren von Webhook-Nachrichten ist auch für die Effizienz hilfreich. So können wir beispielsweise Abonnenten abmelden, die unsere Protokolle lange Zeit nicht erfolgreich empfangen haben, und die Liste dadurch korrekt und aktuell halten. Weitere Informationen zum Protokollieren von Webhook-Nachrichten finden Sie in diesem Video von NearForm. Ein gutes Tool für das Webhook-Logging ist außerdem dieser Node.js-Logger.
Ein Abonnementmodell mit Ablaufdatum verwenden
Am besten ermöglichen Sie es Nutzern, ein Ablaufdatum für ihr Abonnement festzulegen. Ein Ablaufdatum allein bewirkt zwar nicht viel, doch in Kombination mit anderen Sicherheitsmaßnahmen bietet es eine zusätzliche Sicherheitsebene.
In Kombination mit verschiedenen Verschlüsselungs-, Authentifizierungs- und Autorisierungsmethoden trägt die zeitliche Begrenzung von Berechtigungen für einen Server oder Client zu einer mehrschichtigen Absicherung bei. Außerdem verkürzen Ablaufdaten den Zeitraum, in dem ein Angreifer eine Schwachstelle in unserer Sicherheit finden kann, etwa durch gestohlene Anmeldedaten. Denn nach Ablauf muss der Client den Abonnementprozess erneut durchlaufen.
Webhook-Sicherheit gewährleisten
Die Verschlüsselung unserer Webhook-Nachrichten bildet die Grundlage dafür, dass Clients Nachrichten überprüfen können. Weitere Sicherheitsmaßnahmen bauen darauf auf und bieten in Kombination einen umfassenderen Schutz.
Denken Sie daran: Webhooks sollen Clients in der Regel über Ereignisse in Ihrem System informieren. Die meisten dieser Ereignisse – etwa neue GitHub-PR-Anfragen oder neue Follower eines Abonnements – sollten harmlos sein. Daher haben Angreifer kaum Interesse daran, diese Kommunikation zu manipulieren. Es wird dringend empfohlen, keine hochsensiblen Daten über Webhooks zu senden.
Ein umfassender Sicherheitsansatz beginnt damit, Sicherheitsmaßnahmen auszuwählen, die zur Domäne Ihrer Anwendung und zur Art der gesendeten Informationen passen. Updates zu bevorstehenden Ereignissen erfordern beispielsweise weniger Sicherheitsmaßnahmen als Nachrichten mit detaillierten Informationen zu einzelnen Clients. Wenn Sie Ihren Ansatz anpassen und überlappende Sicherheitsebenen einrichten, können Sie mit größerer Zuversicht davon ausgehen, dass Ihr Code und Ihre Clientdaten vor den verschiedenen Arten von Schwachstellen geschützt sind, die uns heute begegnen.
