Webhooks sicher empfangen
Endpoint-Lifecycle, Raw-Body-Signatur, SSRF-Grenzen, Rotation und Zustellwiederholung.
10 Min. LesezeitEndpoint anlegen
Registriere eine öffentliche HTTPS-URL und die benötigten Eventtypen. Das Signing Secret erscheint nur in der Erstellungsantwort und in ihrem exakten Idempotenz-Replay. Speichere es sofort verschlüsselt.
POST /v1/club/webhook-endpoints
Authorization: Bearer <token>
Idempotency-Key: 018f-create-webhook
Content-Type: application/json
{
"name": "Primary event receiver",
"url": "https://partner.example/webhooks/padel-lab",
"event_types": ["booking.updated", "match.completed"]
}Signatur vor dem Parsen prüfen
Berechne HMAC-SHA-256 über timestamp + "." + rawBody. Vergleiche die Signatur in konstanter Zeit und prüfe ein enges Zeitfenster, bevor du JSON parst oder fachliche Aktionen startest.
import {createHmac, timingSafeEqual} from "node:crypto";
function verifyWebhook(
timestamp: string | undefined,
signature: string | undefined,
rawBody: Buffer,
secret: string,
) {
if (!timestamp || !signature) return false;
const signed = Buffer.concat([
Buffer.from(timestamp),
Buffer.from("."),
rawBody,
]);
const expected = "v1=" + createHmac("sha256", secret)
.update(signed)
.digest("hex");
const expectedBytes = Buffer.from(expected);
const signatureBytes = Buffer.from(signature);
const sentAt = /^\d{10}$/.test(timestamp) ? Number(timestamp) * 1000 : NaN;
const fresh = Number.isSafeInteger(sentAt) && Math.abs(Date.now() - sentAt) <= 300_000;
return fresh &&
signatureBytes.length === expectedBytes.length &&
timingSafeEqual(expectedBytes, signatureBytes);
}Zustellheader
| Header | Verwendung |
|---|---|
| Padel-Lab-Timestamp | Unix-Zeit der Signatur |
| Padel-Lab-Signature | v1=<hex-hmac> |
| Padel-Lab-Delivery | Zustellungs-ID |
| Padel-Lab-Event | Eventtyp |
Zielnetz-Schutz
- Nur öffentliches HTTPS
- Keine URL-Zugangsdaten oder Fragmente
- Keine Redirects
- Private und reservierte Netze werden blockiert
- DNS wird vor jeder Auslieferung erneut geprüft
Retries und Auto-Disable
Zustellversuche erfolgen sofort sowie nach 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden, 8 Stunden, 24 Stunden und 48 Stunden. Nach 20 aufeinanderfolgenden Fehlern wird der Endpoint deaktiviert und im Club-Portal markiert.
Secret rotieren
POST /webhook-endpoints/{id}/rotate-secret benötigt einen neuen Idempotency-Key. Die Antwort zeigt das neue Secret einmalig; dieselbe Rotation kann nur mit exakt demselben Key sicher replayt werden.