Ein Webhook ist der schnellste Weg, ein fremdes System an Ihre Automatisierung zu koppeln: Der Zahlungsdienstleister, der Onlineshop oder das Ticketsystem schickt bei jedem Ereignis eine Nachricht an eine feste Adresse, und Ihr Workflow startet sofort. Der Haken: Diese Adresse ist öffentlich. Wer sie kennt, kann Ihren Workflow auslösen – und ihm eine gefälschte Meldung wie „Zahlung eingegangen“ oder „Bestellung storniert“ unterschieben. Dieser Artikel zeigt, wie Sie prüfen, ob ein eingehender Webhook wirklich vom angegebenen Absender stammt, und wie Sie das in n8n mit ein paar Knoten sauber umsetzen. Geschrieben für Geschäftsführer und Verantwortliche, die Systeme über Webhooks verbinden und wissen wollen, ob sie den hereinkommenden Daten trauen können.
Warum eine Webhook-URL allein kein Ausweis ist
Ein Webhook-Endpunkt ist im Kern nur eine URL, die auf HTTP-Anfragen wartet. Sobald der Workflow veröffentlicht ist, kann jeder, der die Adresse kennt, eine Anfrage dorthin schicken. Und Adressen sind kein Geheimnis: Sie stehen in Server-Logs, in Browser-Verläufen, in der Konfiguration von Drittdiensten. Ein Angreifer muss also nicht „einbrechen“ – er muss nur eine plausibel aussehende Nachricht an eine bekannte Adresse senden.
Kritisch wird das in dem Moment, in dem Ihr Workflow auf die Meldung handelt: eine Bestellung als bezahlt markiert, eine Gutschrift auslöst, einen Datensatz im CRM anlegt, eine Ware zur Auslieferung freigibt. Eine erfundene „Zahlung eingegangen“-Nachricht kann dann reale Folgen haben – ohne dass jemals Geld geflossen ist. Wie ein Webhook technisch funktioniert und wann er die richtige Wahl gegenüber regelmäßigem Abfragen ist, habe ich in Webhook oder Polling beschrieben; hier geht es um die Frage danach: Wie stelle ich sicher, dass die Nachricht echt ist?
Der Webhook-Node in n8n bietet dafür eingebaut Basic Auth, Header Auth und JWT. Das ist genau richtig, wenn Sie selbst den Aufrufer kontrollieren – etwa ein zweiter eigener Workflow. Bei den häufigsten Absendern hilft es aber nicht: Stripe, GitHub oder Ihr Shop-System fragen Sie nicht nach einem Basic-Auth-Passwort. Sie signieren stattdessen ihre Nachrichten. Genau diese Signatur müssen Sie prüfen.
Eine Webhook-URL ist keine Zugangskontrolle, sondern nur eine Adresse. Wer sie kennt, kann Ihren Workflow auslösen und ihm gefälschte Ereignisse unterschieben. Verlässlich wird ein eingehender Webhook erst, wenn Ihr Workflow prüft, ob die Nachricht wirklich vom angegebenen Absender stammt und unterwegs nicht verändert wurde – genau das leistet eine Signaturprüfung.
Zwei Wege, einen Webhook abzusichern
In der Praxis gibt es zwei Verfahren, und der Unterschied ist wichtig.
Das gemeinsame Geheimwort (Token): Der Absender schickt bei jeder Anfrage ein vereinbartes Passwort in einem Kopfzeilen-Feld mit, und Ihr Workflow vergleicht es mit dem hinterlegten Wert. GitLab nutzt das etwa mit dem Header X-Gitlab-Token. Das lässt sich in n8n direkt über die Header Auth des Webhook-Node abbilden – Sie tragen erwarteten Feldnamen und Wert ein, und n8n weist alles ab, was nicht passt. Der Nachteil: Das Token reist in jeder Anfrage im Klartext mit, wer es abfängt, kann es wiederverwenden, und es sagt nichts darüber aus, ob der Nachrichteninhalt unterwegs verändert wurde. GitLab selbst bezeichnet das einfache Token laut Dokumentation inzwischen als nicht empfohlen für neue Webhooks.
Die Signatur (HMAC): Der Absender berechnet aus dem genauen Nachrichteninhalt und einem geteilten Geheimnis eine kryptografische Prüfsumme und legt sie in die Kopfzeile. Sie berechnen dasselbe mit Ihrer Kopie des Geheimnisses nach. Stimmen beide Werte überein, ist zweierlei belegt: Die Nachricht stammt vom echten Absender und wurde auf dem Weg nicht verändert. Stripe, GitHub und Shopify arbeiten alle so. Für dieses Verfahren reicht die eingebaute Authentifizierung nicht – Sie prüfen die Signatur selbst.
Wie eine Signaturprüfung funktioniert
Hinter der Signatur steht ein HMAC (Hash-based Message Authentication Code). Sie und der Absender teilen ein Geheimnis, das sonst niemand kennt. Der Absender hängt dieses Geheimnis gedanklich an den Nachrichteninhalt, bildet daraus einen Hash-Wert und schickt ihn als Signatur mit. Sie wiederholen dieselbe Rechnung mit Ihrer Kopie des Geheimnisses. Kommt derselbe Wert heraus, ist die Nachricht echt. Ändert sich auch nur ein einziges Byte am Inhalt, fällt die Prüfsumme völlig anders aus – Manipulation fliegt sofort auf.
Die Details unterscheiden sich je Anbieter, folgen aber demselben Muster. Ein Überblick über gängige Dienste:
| Dienst | Signatur-Header und Verfahren |
|---|---|
| Stripe | Stripe-Signature mit t= (Zeitstempel) und v1= (HMAC-SHA256, Hex) |
| GitHub | X-Hub-Signature-256, HMAC-SHA256 als Hex mit Präfix sha256= |
| Shopify | X-Shopify-Hmac-SHA256, HMAC-SHA256 in Base64 |
| GitLab | einfaches Token (X-Gitlab-Token) oder wahlweise HMAC-Signatur |
Wichtig sind zwei Kleinigkeiten, an denen Prüfungen oft scheitern: das Encoding (Stripe und GitHub liefern die Signatur als Hex-Zeichenkette, Shopify als Base64 – Sie müssen im selben Format vergleichen) und der genaue Nachrichtentext. Stripe etwa berechnet die Signatur laut Dokumentation nicht nur über den Inhalt, sondern über die Zeichenkette aus Zeitstempel, einem Punkt und dem Rohtext (t.body). GitHub bildet den HMAC direkt über den rohen Anfragetext und stellt der Signatur sha256= voran.
Signaturprüfung in n8n einrichten
Der entscheidende erste Schritt entscheidet über Erfolg oder Frust: Aktivieren Sie im Webhook-Node die Option „Raw Body“. Damit erhält der Workflow den Nachrichtentext genau so, wie der Absender ihn gesendet hat. Ohne diese Option zerlegt n8n eingehendes JSON in ein Objekt – und wenn Sie es später wieder zusammensetzen, um den HMAC zu bilden, ändern sich Reihenfolge und Leerzeichen minimal. Die Signatur passt dann nie. Stripe weist ausdrücklich darauf hin, dass der Text die unveränderte UTF-8-Zeichenkette sein muss; Shopify betont, den Rohtext vor jeder Verarbeitung zu sichern.
Danach läuft die Prüfung in wenigen Schritten:
- Signatur auslesen. Der Webhook-Node stellt die Kopfzeilen unter
$json.headersbereit (Feldnamen kommen kleingeschrieben an, also etwa$json.headers['stripe-signature']). - HMAC berechnen. Der eingebaute Crypto-Node beherrscht die Aktion „Hmac“ mit Typ SHA256 und Ausgabe in Hex oder Base64 – passend zum jeweiligen Dienst. Alternativ berechnen Sie den Wert in einem Code-Node mit Bordmitteln.
- Vergleichen – aber richtig. Hier lauert eine Falle: Ein simpler Gleichheitsvergleich (etwa im IF-Node) ist angreifbar, weil er je nach Übereinstimmung minimal unterschiedlich lange braucht. GitHub, Stripe und Shopify empfehlen deshalb übereinstimmend einen zeitkonstanten Vergleich über
crypto.timingSafeEqual. Diesen erreichen Sie zuverlässig nur im Code-Node; die Crypto-plus-IF-Variante ist der pragmatische, aber schwächere Weg. - Erst prüfen, dann handeln. Läuft der Vergleich negativ, bricht der Workflow ab (etwa mit „Stop And Error“) oder antwortet mit einem Fehlercode. Kein weiterer Schritt darf auf einen ungeprüften Inhalt zugreifen.
Ein Hinweis zum Code-Node: Das Node.js-Modul crypto ist aus Sicherheitsgründen nicht überall freigeschaltet. Auf n8n Cloud steht es bereits zur Verfügung; bei einer selbst gehosteten Instanz erlauben Sie es laut Dokumentation über die Umgebungsvariable NODE_FUNCTION_ALLOW_BUILTIN=crypto (bei aktiven Task Runnern auf dem Runner). Das geteilte Geheimnis selbst gehört nicht offen in den Workflow, sondern in die Zugangsdaten-Verwaltung – wie Sie Credentials in n8n grundsätzlich schützen, habe ich in Automatisierungen absichern zusammengefasst.
Der Faktor Zeit: Replay-Angriffe abwehren
Eine gültige Signatur allein genügt noch nicht. Wer eine echte, korrekt signierte Anfrage einmal mitgeschnitten hat, kann sie später erneut abschicken – die Signatur stimmt ja weiterhin. Das nennt man einen Replay-Angriff. Die Abwehr hat zwei Hebel.
Erstens der Zeitstempel: Stripe bindet die Signatur an den Zeitpunkt (t=) und verwirft in seinen Bibliotheken standardmäßig Anfragen, deren Zeitstempel mehr als fünf Minuten (300 Sekunden) zurückliegt. Prüfen Sie also, ob die Nachricht frisch ist, und weisen Sie zu alte ab. Zweitens die Idempotenz: Bauen Sie den Workflow so, dass dieselbe Nachricht zweimal verarbeitet keinen Schaden anrichtet. Nicht jeder Dienst liefert einen Zeitstempel mit – umso wichtiger ist dann der zweite Hebel. Wie Sie doppelte Aktionen in Automatisierungen verhindern, ist deshalb der natürliche Begleiter jeder Webhook-Absicherung.
Die häufigsten Fehler
In der Praxis scheitern Signaturprüfungen fast immer an denselben Stellen:
- Der Text wurde neu zusammengesetzt. Ohne „Raw Body“ prüfen Sie gegen ein re-serialisiertes JSON statt gegen das Original – die Signatur passt nie.
- Falsches Encoding. Hex mit Base64 verglichen. Achten Sie auf das Format, das der jeweilige Dienst verwendet.
- Einfacher Gleichheitsvergleich statt eines zeitkonstanten – eine vermeidbare Schwachstelle.
- Kein Zeitfenster geprüft, sodass mitgeschnittene Anfragen beliebig wiederholbar bleiben.
- Zuerst verarbeitet, dann geprüft. Die Prüfung gehört an den Anfang, bevor der Inhalt irgendetwas auslöst.
Keiner dieser Punkte ist aufwändig – zusammen entscheiden sie aber darüber, ob die Absicherung echt greift oder nur so aussieht.
Was das für Ihren Betrieb heißt
Immer wenn eine Automatisierung auf externe Ereignisse mit echten Folgen reagiert – Geld, Warenbestand, Kundendaten –, muss der Endpunkt wissen, wer da anklopft. Die Faustregel ist einfach: Bevorzugen Sie Dienste und Verfahren, die signieren, prüfen Sie die Signatur, bevor Ihr Workflow irgendetwas tut, und sichern Sie sich mit einer Frische-Prüfung oder Idempotenz gegen Wiederholungen ab. Das sind ein paar Knoten, kein Großprojekt. Bei der konkreten Einrichtung solcher Trigger und Prüfungen unterstütze ich Sie in der n8n-Beratung.
Wenn Sie unsicher sind, ob Ihre bestehenden Webhooks abgesichert sind oder wo ein Angreifer heute eine gefälschte Meldung einschleusen könnte, schauen wir uns das im kostenlosen Prozess-Check gemeinsam an – ehrlich, auch wenn die Antwort manchmal lautet, dass ein einzelner Endpunkt bislang völlig offen stand.