Sécurité et livraison des webhooks
Vérifiez les signatures des webhooks, comprenez le comportement des nouvelles tentatives et résolvez les problèmes de livraison.
Pourquoi c’est important
La vérification des signatures prouve que les données reçues sont authentiques et non modifiées. Comprendre le comportement des nouvelles tentatives et de la désactivation automatique vous aide à construire des intégrations résilientes.
Vérification des signatures
Chaque livraison est signée avec le secret de signature de votre point de terminaison en utilisant HMAC-SHA256. La signature couvre l’horodatage et le corps de la requête pour prévenir les attaques par rejeu.
Le contenu signé est l’horodatage ISO 8601 et le corps JSON joints par un point :
<timestamp>.<body>
Ruby
timestamp = request.headers["X-Webhook-Timestamp"]
signature = request.headers["X-Webhook-Signature"]
body = request.body.read
expected = OpenSSL::HMAC.hexdigest("SHA256", signing_secret, "#{timestamp}.#{body}")
if ActiveSupport::SecurityUtils.secure_compare(expected, signature)
# La signature est valide
else
head :unauthorized
end
Node.js
const crypto = require("crypto");
function verifySignature(signingSecret, timestamp, body, signature) {
const expected = crypto
.createHmac("sha256", signingSecret)
.update(`${timestamp}.${body}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
Python
import hmac
import hashlib
def verify_signature(signing_secret, timestamp, body, signature):
expected = hmac.new(
signing_secret.encode(),
f"{timestamp}.{body}".encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Prévention des attaques par rejeu
Comparez X-Webhook-Timestamp avec l’heure actuelle et rejetez les requêtes datant de plus de 5 minutes.
Rotation de votre secret de signature
Cliquez sur Rotation du secret sur la page de détail du webhook pour générer un nouveau secret de signature. L’ancien secret est immédiatement invalidé.
Pour effectuer une rotation sans interruption de service :
- Déployez votre point de terminaison pour qu’il accepte les signatures provenant de l’ancien et du nouveau secret
- Effectuez la rotation du secret dans Kit
- Vérifiez que les livraisons réussissent avec le nouveau secret
- Supprimez l’ancien secret de votre point de terminaison
Livraison et nouvelles tentatives
Kit effectue jusqu’à 5 tentatives de livraison lorsque votre point de terminaison est injoignable ou renvoie une erreur.
| Tentative | Comportement |
|---|---|
| 1 | Immédiate |
| 2-5 | Délais d’attente croissants de manière polynomiale |
| Paramètre | Valeur |
|---|---|
| Délai de connexion | 10 secondes |
| Délai de lecture | 15 secondes |
Une réponse 2xx marque la livraison comme terminée. Tout autre code de statut ou un délai d’attente dépassé la marque comme en erreur et déclenche une nouvelle tentative.
Désactivation automatique
Après 15 échecs de livraison consécutifs sur l’ensemble des événements, Kit désactive automatiquement le webhook.
Lorsqu’il est désactivé :
- Aucune livraison supplémentaire n’est tentée
- Le statut passe à Désactivé avec un horodatage
disabled_at
Cliquez sur Reprendre pour le réactiver. Cela réinitialise le compteur d’échecs et rétablit le webhook en mode actif.
Journaux de livraison
Chaque point de terminaison webhook dispose d’un onglet Livraisons affichant les 50 livraisons les plus récentes. Chaque entrée comprend :
| Champ | Description |
|---|---|
| Événement | Type d’événement ayant déclenché la livraison |
| Statut | pending, in_progress, completed ou errored |
| Tentatives | Nombre de tentatives de livraison |
| En-têtes de requête | En-têtes envoyés avec la requête |
| Réponse | Code de statut HTTP ou message d’erreur |
| Horodatage | Date de création de la livraison |
Statuts de livraison
| Statut | Signification |
|---|---|
pending |
Créé, en attente d’envoi |
in_progress |
En cours de livraison |
completed |
Le point de terminaison a renvoyé une réponse 2xx |
errored |
Toutes les tentatives épuisées ou le point de terminaison a renvoyé une erreur |
Conservation des données
Les journaux de livraison sont conservés pendant 30 jours, puis automatiquement supprimés. Stockez les données de votre côté si vous avez besoin d’une conservation plus longue.
Exigences relatives aux URL
- HTTPS requis — Les points de terminaison HTTP sont rejetés
- Adresses IP publiques uniquement — Les URL pointant vers des adresses privées (localhost, 10.x.x.x, 192.168.x.x, etc.) sont bloquées
- Les URL sont validées lors de la création et avant chaque livraison
Dépannage
| Problème | Cause | Solution |
|---|---|---|
| Signature incorrecte | Mauvais secret de signature ou corps modifié avant la vérification | Vérifiez avec le corps brut de la requête et le secret actuel |
| Livraisons en dépassement de délai | Le point de terminaison met plus de 15 secondes à répondre | Renvoyez 200 immédiatement et traitez de manière asynchrone |
| Webhook désactivé automatiquement | 15 échecs consécutifs | Corrigez votre point de terminaison, puis cliquez sur Reprendre |
| URL rejetée | Adresse IP privée ou URL HTTP | Utilisez une URL HTTPS pointant vers une adresse IP publique |
| Événements non déclenchés | Webhook en pause ou type d’événement non souscrit | Vérifiez le statut du webhook et les événements souscrits |
Aide-mémoire
- Copiez votre secret de signature depuis la page de détail du webhook
- Implémentez la vérification de signature HMAC-SHA256 dans votre point de terminaison
- Rejetez les requêtes dont l’horodatage dépasse 5 minutes
- Renvoyez un code de statut
2xxdans un délai de 15 secondes - Gérez les nouvelles tentatives de manière idempotente (vous pouvez recevoir le même événement plusieurs fois)
- Surveillez les journaux de livraison pour détecter les erreurs
- Configurez des alertes pour être informé lorsqu’un webhook est désactivé automatiquement