Webhooks sind eine der leistungsfähigsten Möglichkeiten, Echtzeit-Updates von Drittanbieterdiensten zu empfangen. Ein einziger HTTP-POST von Stripe, GitHub, Shopify oder Twilio kann wichtige Geschäftslogik in Ihrer Anwendung auslösen – das Belasten eines Kunden, das Aktualisieren eines Repositories, das Versenden einer Bestellung oder das Senden einer Bestätigungs-SMS.
Doch jede Webhook-Anfrage kommt über das öffentliche Internet an. Und das bedeutet, dass jeder, der Ihre Webhook-URL errät oder entdeckt, bösartige Payloads senden kann, die völlig legitim aussehen. Ohne ordnungsgemäße Authentifizierung kann Ihre Anwendung nicht zwischen einem echten Ereignis und einem gefälschten unterscheiden.
Hier kommt die Webhook-Signaturprüfung ins Spiel. Sie ist ein einfacher, standardisierter Mechanismus, der sicherstellt, dass jede eingehende Webhook-Anfrage tatsächlich von dem Dienst stammt, den Sie erwarten, und während der Übertragung nicht verändert wurde.
In diesem umfassenden Leitfaden erfahren Sie genau, wie die Webhook-Signaturprüfung funktioniert und wie Sie sie in gängigen Sprachen korrekt implementieren. Sie sehen auch häufige Fehler, die vermieden werden sollten, und wie Sie alles End-to-End testen können – schnell und zuverlässig.
Was ist Webhook-Signaturprüfung?
Die Webhook-Signaturprüfung ist der Prozess, bei dem bestätigt wird, dass eine eingehende Webhook-Anfrage tatsächlich von dem Dienst stammt, den Sie erwarten, und nicht manipuliert wurde.
Die meisten Anbieter verwenden HMAC (Hash-based Message Authentication Code) mit SHA-256 oder SHA-512. Der Dienst berechnet:
signature = HMAC-SHA256(secret_key, payload)
Dann senden sie die Signatur in einem Header (üblicherweise X-Signature, Signature oder X-Hub-Signature-256).
Ihr Server:
- Empfängt die Payload als Rohdaten (wichtig!)
- Berechnet den HMAC erneut mit Ihrem gespeicherten Geheimnis
- Vergleicht die berechnete Signatur mit der empfangenen
Wenn sie exakt übereinstimmen, verarbeiten Sie den Webhook. Andernfalls geben Sie HTTP 401 oder 403 zurück.
Warum HMAC-SHA256 der Industriestandard ist
Anbieter wählen HMAC-SHA256 aus guten Gründen:
- Schnell: Selbst auf bescheidener Hardware ist es blitzschnell.
- Sicher: SHA-256 ist im Jahr 2025 ungebrochen.
- Einfach: Ein geheimer Schlüssel, keine Verwaltung von Public/Private-Key-Paaren.
- Standardisiert: Bibliotheken in jeder Sprache implementieren es korrekt.
GitHub, Stripe, Shopify, Slack und Dutzende andere verwenden alle HMAC-SHA256.
So implementieren Sie die Webhook-Signaturprüfung in Node.js
Beginnen wir mit einem realen Beispiel in Node.js.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const computedSignature = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(computedSignature),
Buffer.from(signature)
);
}
Wichtige Hinweise:
- Verwenden Sie immer
crypto.timingSafeEqual, um Timing-Angriffe zu verhindern. - Verwenden Sie niemals
===bei Strings – es ist anfällig. - Verwenden Sie
Buffer.from(), um einen Vergleich mit konstanter Zeit zu gewährleisten.
Beispiel für Express-Middleware:
app.post('/webhooks/stripe', (req, res, next) => {
const signature = req.headers['stripe-signature'];
const secret = process.env.STRIPE_WEBHOOK_SECRET;
// Get raw body (Express needs middleware to preserve raw body)
const rawBody = req.rawBody || req.body; // use body-parser with verify option
if (!verifyWebhookSignature(rawBody, signature, secret)) {
return res.status(401).send('Invalid signature');
}
// Signature is valid → process the event
next();
});
Python-Implementierung (FastAPI + Pydantic)
from fastapi import FastAPI, Request, HTTPException
import hmac
import hashlib
app = FastAPI()
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
computed = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed, signature)
@app.post("/webhooks/github")
async def github_webhook(request: Request):
signature = request.headers.get("X-Hub-Signature-256")
if not signature:
raise HTTPException(status_code=401, detail="Missing signature")
payload = await request.body()
if not verify_signature(payload, signature.split('=')[1], SECRET):
raise HTTPException(status_code=401, detail="Invalid signature")
# Process webhook
return {"status": "ok"}
Häufige Fallstricke von Entwicklern (und wie man sie vermeidet)
1. Verwendung von JSON.stringify() oder geparstem Body
Viele Frameworks parsen JSON automatisch. Dies unterbricht die Überprüfung, da Leerzeichen, Schlüsselreihenfolge und Formatierung unterschiedlich sind.
Lösung: Erfassen Sie immer den Raw-Body vor dem Parsen.
In Express: Verwenden Sie body-parser mit { verify: true }
In FastAPI: Verwenden Sie await request.body()
2. String-Vergleiche mit ===
Timing-Angriffe können Informationen preisgeben. Verwenden Sie crypto.timingSafeEqual oder hmac.compare_digest.
3. Speichern von Geheimnissen im Code
Verwenden Sie Umgebungsvariablen oder Geheimnis-Manager (AWS Secrets Manager, HashiCorp Vault usw.).
4. Vergessen, Replay-Angriffe zu behandeln
Die meisten Anbieter fügen einen Zeitstempel hinzu. Überprüfen Sie, ob das Ereignis aktuell ist (z. B. innerhalb von 5 Minuten).
const timestamp = req.headers['X-Signature-Timestamp'];
if (Date.now() - timestamp > 5 * 60 * 1000) {
return res.status(401).send('Timestamp too old');
}
5. Verwendung von SHA-1 (passiert immer noch!)
GitHub hat SHA-1 im Jahr 2022 eingestellt. Verwenden Sie immer SHA-256.
Testen der Webhook-Signaturprüfung mit Apidog
Das manuelle Testen von Webhooks ist mühsam. Sie senden eine Anfrage, überprüfen Protokolle, korrigieren, wiederholen.
Apidog macht dies trivial:
Klicken Sie in Ihrem Apidog-Projekt in der linken Seitenleiste auf das +-Symbol und wählen Sie "New Other Protocol APls" > "Webhook".
Nachdem Sie den Webhook erstellt haben, füllen Sie die folgenden Felder im Editor aus:Anfragemethode: Typischerweise POST.Webhook-Name: Dieser erscheint in der API-Dokumentation und im OpenAPI-Export, z. B. order.Debug-URL (optional): Die tatsächliche URL, die zum Senden von Testanfragen verwendet wird. Hinweis: Dies dient nur zu Testzwecken und wird nicht in der Dokumentation enthalten sein.Weitere Informationen: Wie z. B. der Anfragetext.
Klicken Sie auf Speichern, sobald Sie alle erforderlichen Felder ausgefüllt haben.
Geben Sie einfach Ihre Webhook-URL in das Feld Debug-URL ein und klicken Sie dann auf Senden, um einen Webhook-Aufruf zu simulieren.
Ich habe Stunden an Debugging-Zeit mit Apidogs Webhook-Simulator gespart. Er unterstützt sogar das exakte stripe-signature-Format von Stripe und das sha256=...-Präfix von GitHub.
Praxisbeispiel: Überprüfen von Stripe-Webhooks
Stripe verwendet ein spezielles Header-Format:
stripe-signature: t=1681234567,v1=abc123...,v0=def456...
Sie müssen:
- Den
t=-Zeitstempel extrahieren - Die
v1=-Signatur extrahieren (bevorzugt) - Neu berechnen mit
payload + timestamp - Nur den
v1-Teil vergleichen
Stripe bietet offizielle Bibliotheken zur Bewältigung dieser Komplexität:
const stripe = require('stripe')('sk_...');
stripe.webhooks.constructEvent(payload, sigHeader, endpointSecret);
Aber das Verständnis des zugrunde liegenden HMAC ist entscheidend, wenn Sie es selbst implementieren müssen.
Fortgeschrittene Themen: Mehrere Signaturen tolerieren
Einige Anbieter (wie Stripe) senden mehrere Signaturen zur Abwärtskompatibilität. Ihr Code sollte:
- Den Header nach
,aufteilen - Jeden einzelnen versuchen
- Akzeptieren, wenn einer übereinstimmt
Sicherheitsbest-Practices im Jahr 2025
- Webhook-Geheimnisse alle 90 Tage rotieren.
- Nach Möglichkeit kurzlebige Geheimnisse verwenden.
- Fehlgeschlagene Überprüfungen protokollieren, aber niemals das Geheimnis protokollieren.
- Webhook-Endpunkte ratenbegrenzen, um Brute-Force-Angriffe zu verhindern.
- Immer HTTPS verwenden.
Fazit: Kleiner Verifizierungsschritt, großer Sicherheitsgewinn
Die Webhook-Signaturprüfung klingt nach einem kleinen Detail. Aber sie ist der Unterschied zwischen einer sicheren Anwendung und einer, die Angreifer trivial ausnutzen können.
Implementieren Sie sie korrekt, testen Sie sie gründlich mit Tools wie Apidog und schlafen Sie besser, da Sie wissen, dass Ihre Integrationen geschützt sind.
Laden Sie Apidog noch heute kostenlos herunter und überprüfen Sie Ihren ersten Webhook in weniger als 5 Minuten. Es ist der schnellste Weg, um zu beweisen, dass Ihr Code tatsächlich funktioniert.
