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 envoie la charge utile JSON par POST à votre point de terminaison avec ces délais d’attente :
| 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 le reste est un échec, et la façon dont Kit le gère dépend de la nature de cet échec : transitoire ou permanent.
Échecs transitoires (avec nouvelle tentative)
Les échecs transitoires sont des problèmes susceptibles de se résoudre d’eux-mêmes — votre point de terminaison était brièvement surchargé, a dépassé le délai d’attente ou était injoignable. Kit réessaie jusqu’à 5 tentatives avec un délai polynomial (chaque attente plus longue que la précédente).
Un échec est considéré comme transitoire lorsque la réponse est :
- HTTP
500–599(erreurs serveur) - HTTP
408(Request Timeout) - HTTP
429(Too Many Requests) - Une erreur réseau ou un délai d’attente dépassé (connexion refusée, échec DNS, délai de lecture dépassé)
| Tentative | Comportement |
|---|---|
| 1 | Immédiate |
| 2–5 | Délais d’attente croissants de manière polynomiale |
Échecs permanents (sans nouvelle tentative)
Les échecs permanents indiquent que la requête elle-même n’est pas acceptable pour votre point de terminaison et qu’une nouvelle tentative serait inutile. Kit marque la livraison comme en erreur immédiatement et ne réessaie pas.
Un échec est considéré comme permanent lorsque la réponse est tout autre statut 4xx — par exemple 400, 401, 404 ou 410. Si votre point de terminaison renvoie l’un de ces codes par erreur, corrigez la route ou l’authentification de votre côté ; Kit ne réessaiera qu’au déclenchement de l’événement suivant.
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 permanente (4xx) |
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 |
| Livraison en erreur sans nouvelle tentative | Le point de terminaison a renvoyé un 4xx permanent (par ex. 404, 410) |
Corrigez la route, l’authentification ou la méthode ; seules les erreurs transitoires (5xx, 408, 429, réseau/délai dépassé) sont réessayées |
| 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 |
Checklist
- 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