Guides

Guide de sécurité

Webhooks sécurisés : vérifier, protéger contre les replays, surveiller

Un endpoint de webhook est une API publique. Considérez chaque livraison comme non fiable tant que son expéditeur, sa fraîcheur, sa charge et son effet métier n’ont pas été vérifiés.

Les webhooks permettent aux plateformes de paiement, fournisseurs d’identité, systèmes de commerce et services internes de notifier une application lorsqu’un événement survient. Ils sont utiles, car le système récepteur n’a pas besoin d’interroger périodiquement. Ils sont risqués pour la même raison : un endpoint exposé sur Internet peut déclencher une action métier.

Le modèle sûr est simple : vérifiez la requête signée de l’expéditeur avant de la traiter, rejetez les livraisons périmées ou rejouées, rendez l’action métier idempotente et observez chaque décision sans stocker de secrets. Un WAF, un CDN ou une limite de débit peut réduire le trafic indésirable, mais aucun ne prouve qu’une charge de webhook est authentique.

Ne vous fiez pas uniquement à l’adresse IP de l’expéditeur

L’infrastructure de livraison peut changer, les adresses peuvent être partagées et un attaquant peut envoyer une requête directement à l’origine. Utilisez la vérification de signature documentée par le fournisseur comme contrôle d’identité principal, puis ajoutez des contrôles réseau comme couche de soutien.

Commencez par un modèle de menace pour les webhooks

Documentez chaque endpoint avant de configurer les contrôles. Consignez son fournisseur, ses types d’événements, sa méthode d’authentification, le type de contenu et la taille de corps attendus, son comportement de nouvelle tentative, son volume de pointe et l’action métier qu’il peut déclencher. Un événement de paiement confirmé, de réinitialisation de mot de passe et de mise à jour de catalogue ne doivent pas tous recevoir la même politique.

Au minimum, prévoyez ces défaillances :

  • Une requête forgée qui prétend venir d’un fournisseur de confiance.
  • Un événement valide rejoué après avoir déjà été traité.
  • Des livraisons dupliquées ou dans le désordre causées par des nouvelles tentatives normales.
  • Un ancien événement livré après que l’état métier a changé.
  • Une charge malformée, trop volumineuse ou inattendue.
  • Un pic qui épuise le récepteur, la file ou une dépendance aval.

Vérifiez la requête signée avant de l’analyser

Les fournisseurs de webhooks signent généralement une représentation du corps de requête brut à l’aide d’un secret partagé ou d’une clé privée. Respectez exactement le schéma du fournisseur. N’inventez pas une version qui semble compatible : les composants signés, l’encodage, le format d’horodatage et le modèle de rotation des clés font partie du contrat de sécurité.

Une séquence de vérification sûre

  1. Exigez HTTPS et validez le certificat TLS à chaque saut réseau.
  2. Lisez le corps brut exactement une fois, avant que l’analyse JSON ou une normalisation des espaces ne le modifie.
  3. Extrayez les en-têtes de signature et d’horodatage du fournisseur.
  4. Recréez le message signé selon la documentation du fournisseur.
  5. Calculez ou vérifiez la signature avec le secret ou la clé publique actuelle.
  6. Comparez les secrets en temps constant lorsque la plateforme ne fournit pas déjà un vérificateur sûr.
  7. Rejetez les horodatages en dehors d’une courte fenêtre d’acceptation documentée.
  8. Analysez seulement ensuite la charge et décidez si le type d’événement est autorisé pour cet endpoint.

Conservez les clés de signature dans un gestionnaire de secrets, jamais dans le code source ni dans une configuration livrée au navigateur. Prenez en charge le chevauchement lors de la rotation des clés afin qu’un fournisseur puisse passer d’une ancienne clé à une nouvelle sans perdre de livraisons valides. Une signature confirme l’intégrité du message et le détenteur de la clé ; elle n’autorise pas automatiquement tous les types d’événements ou opérations métier.

Empêchez les replays et les effets dupliqués

Une requête valide peut être envoyée plus d’une fois. Les fournisseurs relancent une livraison lorsqu’ils ne reçoivent pas rapidement de réponse concluante, et un attaquant qui intercepte une livraison valide peut tenter de la rejouer. Utilisez à la fois la fraîcheur et une idempotence durable.

  • Fraîcheur : rejetez un ancien horodatage signé. La fenêtre doit couvrir une dérive d’horloge et un délai de transit réalistes, pas plusieurs heures ou jours par défaut.
  • Suivi des replays : stockez un ID d’événement, un nonce de signature ou un ID de livraison fournisseur suffisamment longtemps pour rejeter une requête répétée durant la fenêtre de menace.
  • Actions métier idempotentes : enregistrez l’ID d’événement traité et rendez les écritures aval sûres à répéter. Un événement de paiement dupliqué ne doit pas créer un envoi ou un crédit dupliqué.
  • Ordonnancement : ne supposez pas que les événements arrivent dans l’ordre. Récupérez l’état courant depuis l’API faisant autorité lorsqu’un événement peut être remplacé.

Utilisez une contrainte de base de données, une file durable ou un magasin transactionnel d’idempotence plutôt qu’une map de processus en mémoire. Les multiples instances applicatives et les redémarrages rendent la mémoire locale peu fiable.

Validez la charge et limitez le travail

Après vérification de l’expéditeur, traitez la charge comme une entrée non fiable. Validez son schéma, ses champs obligatoires, ses valeurs d’énumération et sa taille avant qu’elle n’atteigne un traitement coûteux. N’autorisez que les méthodes et types de contenu attendus. Rejetez un corps de requête trop volumineux avant de l’analyser.

Ne rendez pas une route de webhook largement permissive parce qu’un fournisseur doit l’appeler. Un challenge navigateur peut convenir au trafic humain suspect, mais il cassera les callbacks de machine à machine. Utilisez plutôt des règles de route étroites, une limite de débit tenant compte du fournisseur, des limites de taille de corps et un vérificateur de signature explicite dans l’application.

Pour un endpoint à forte valeur, séparez la réception du traitement. Vérifiez l’événement, persistez un enregistrement durable minimal, renvoyez rapidement une réponse de succès, puis traitez-le de façon asynchrone. Cela réduit les nouvelles tentatives du fournisseur et donne à l’équipe un endroit contrôlé pour gérer les défaillances temporaires de dépendances ou les événements en dead letter.

Protégez la périphérie et l’origine

Placez l’endpoint derrière le même chemin de livraison contrôlé que le reste de l’application, sans vous fier à la périphérie comme seul contrôle :

  • N’exposez que le nom d’hôte et le chemin requis.
  • Autorisez les méthodes et types de contenu exacts utilisés par le fournisseur.
  • Appliquez un budget de débit de requêtes et de concurrence spécifique à l’endpoint.
  • Gardez l’origine privée ou refusez par défaut les accès publics directs.
  • Authentifiez la connexion périphérie-origine et ne faites confiance aux en-têtes client transférés que depuis le proxy connu.
  • Journalisez ensemble la décision de périphérie, l’ID de requête applicatif, le résultat de signature, l’ID d’événement et le résultat du traitement.

Consultez Protection des API à la périphérie, Limitation de débit et Comment protéger votre serveur d’origine pour les contrôles environnants.

Testez les modes de défaillance avant la production

Utilisez un endpoint hors production et les livraisons de test du fournisseur pour exercer les cas valides et invalides. Testez une signature invalide, un horodatage expiré, un événement dupliqué, un champ obligatoire manquant, un corps surdimensionné, un type d’événement inconnu, une clé tournée, une file lente et une défaillance aval. Confirmez qu’une nouvelle tentative valide ne répète pas un effet métier.

N’utilisez pas de secrets de production dans les journaux ou les fixtures de test. Masquez les en-têtes d’autorisation, signatures, corps contenant des données personnelles et identifiants clients. Ne conservez que les champs nécessaires à l’investigation d’une livraison : horodatage, ID de requête, fournisseur, endpoint, type d’événement, résultat de vérification, statut de réponse et ID de corrélation sûr.

Liste de contrôle opérationnelle

Avant qu’un endpoint ne soit mis en ligne, confirmez que la bibliothèque ou l’algorithme officiel de vérification de signature du fournisseur est utilisé ; que la protection contre les replays et l’idempotence durable sont testées ; que les types d’événements sont sur une liste d’autorisation ; que des limites de corps et de concurrence existent ; que les nouvelles tentatives sont comprises ; que l’accès direct à l’origine est bloqué ; que les secrets peuvent être tournés ; et que les alertes distinguent le trafic rejeté des échecs de traitement.

Références faisant autorité

Sécurisez les intégrations qui font avancer votre activité

Échangez avec Optimi sur les contrôles API à la périphérie, la protection de l’origine et l’observabilité des livraisons de webhooks.

Évaluer la sécurité des webhooks