Logo StartupKit
FR

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 :

  1. Déployez votre point de terminaison pour qu’il accepte les signatures provenant de l’ancien et du nouveau secret
  2. Effectuez la rotation du secret dans Kit
  3. Vérifiez que les livraisons réussissent avec le nouveau secret
  4. 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 500599 (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 2xx dans 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

Tapez pour rechercher...