← Blog Opérations SOC

Webhook du SOC : une signature valide ne prouve pas un événement nouveau

Séparez signature, fraîcheur, identité et effet du traitement pour recevoir des webhooks sans transformer une retransmission en seconde action.

Périmètre des intégrations : Seculogik utilise une architecture indépendante des sources pour ingérer les alertes et événements de sécurité via son propre modèle de données. Wazuh et OpenSearch sont les premières intégrations. Les autres sources citées correspondent à des connecteurs prévus ; leur disponibilité doit être confirmée pour chaque évaluation.

Un connecteur reçoit une notification signée, crée un dossier et lance le suivi prévu. L’émetteur ne reçoit pas la réponse attendue et renvoie la notification. La signature peut encore être correcte, alors que le travail a déjà commencé. Une validation cryptographique ne suffit donc pas à décider de recommencer l’action.

Pour réceptionner un webhook, nous recommandons de séparer quatre questions : le message est-il authentifié selon le contrat prévu, sa livraison est-elle acceptable dans le temps, quelle occurrence représente-t-il et quel traitement a réellement abouti ? Cette méthode s’applique à différents fournisseurs ; les exemples documentés ci-dessous ne constituent pas des annonces d’intégrations disponibles.

1. Vérifier le message avant de lui confier une décision

GitHub documente une signature calculée à partir du contenu et d’un secret partagé, à vérifier avant de poursuivre le traitement. Cette vérification apporte une garantie selon ce contrat et sous réserve de la protection du secret ; elle ne décide pas à elle seule de l’action métier à autoriser. Source : GitHub, validation des livraisons

Notre recommandation : décrire le contrat de réception pour chaque source. Identifiez le point d’entrée, l’environnement, l’organisation, les types de messages acceptés, le secret attendu et les éléments effectivement couverts par la signature. Un identifiant placé dans un en-tête ne devient pas automatiquement une preuve authentifiée. Vérifiez sa protection et son usage avant d’en faire une clé de confiance.

Une réception ne devrait pas pouvoir choisir librement l’identité ou le périmètre sous lequel elle sera traitée. Rapprochez-la de la configuration autorisée du connecteur. Après authentification, contrôlez encore le type, l’action demandée, les champs requis et les ressources concernées. Un message authentique peut rester hors du besoin prévu.

2. Conserver les données nécessaires à la vérification

La documentation Stripe précise que la vérification utilise le corps brut reçu et le secret associé au point d’entrée ; une transformation préalable du contenu peut faire échouer le contrôle. Les secrets d’un point d’entrée de test et d’un autre point d’entrée ne sont pas interchangeables. Source : Stripe, erreurs de vérification

Nous recommandons de vérifier le chemin complet jusqu’au récepteur : passerelle, proxy, bibliothèque et traitement du corps. Une tentative de « nettoyage » qui reconstruit le contenu avant validation peut modifier ce qui était signé. Utilisez la procédure documentée pour la version du fournisseur et de la bibliothèque réellement déployées.

En cas d’échec, gardez un motif exploitable sans exposer les secrets ni recopier systématiquement le corps complet dans les logs. Distinguez notamment un message mal formé, une signature absente, une signature incorrecte et un problème de configuration. Un compteur global de refus ne permet pas de comprendre quelle étape doit être corrigée.

3. Séparer la fraîcheur de la livraison et l’identité de l’événement

Stripe inclut un horodatage dans les données signées pour permettre un contrôle de fraîcheur. Une nouvelle tentative de livraison reçoit une nouvelle signature et un nouvel horodatage. Une livraison récente peut donc concerner un événement déjà reçu. Source : Stripe, réception des événements

Notre recommandation : documenter séparément l’heure de l’événement, celle de la livraison et celle de la réception locale. Lorsque le protocole fournit une fraîcheur vérifiable, appliquez son contrôle avec une horloge fiable et une tolérance adaptée au contrat. Ne réglez pas les difficultés de reprise en supprimant silencieusement cette vérification.

L’identité demande son propre examen. GitHub indique que l’en-tête de livraison conserve la même valeur lors d’une nouvelle livraison demandée. Cet exemple montre pourquoi une reprise ne doit pas être assimilée à une nouvelle occurrence simplement parce qu’elle arrive plus tard. Source : GitHub, bonnes pratiques

Définissez la clé de suivi à partir du contrat de la source, avec son périmètre d’unicité : fournisseur, organisation, environnement ou abonnement selon la source. Évitez qu’un identifiant non validé puisse réserver cette clé et empêcher ensuite un événement légitime d’être traité. Une collision de contenu pour une même identité mérite un état d’anomalie explicite.

4. Suivre l’effet réel plutôt qu’un simple marqueur « reçu »

Nous recommandons des états distincts pour la réception acceptée, l’enregistrement durable, le traitement commencé et le résultat confirmé. Un marqueur posé avant une écriture qui échoue peut faire perdre l’événement ; une action réalisée sans résultat enregistré peut être répétée après redémarrage. Examinez ces deux fenêtres de panne.

Le mécanisme de reprise doit empêcher une retransmission de multiplier l’effet déjà obtenu, tout en permettant de terminer un travail interrompu. Cela peut demander une référence de suivi auprès du système destinataire ou une vérification de son état avant de réessayer. La méthode dépend de l’action : ajouter un commentaire, créer un dossier et modifier un état ne présentent pas les mêmes conséquences.

Le code de réponse HTTP demande aussi un contrat clair. Définissez ce qui est durablement pris en charge avant de confirmer la réception, puis comment une erreur du traitement asynchrone deviendra visible. Une réponse positive ne doit pas être présentée au SOC comme une preuve que l’action finale est terminée.

Stripe documente par ailleurs des livraisons multiples et l’absence de garantie d’ordre de réception. Ce comportement propre à cette source justifie d’examiner les hypothèses d’ordre ; il ne définit pas le contrat de tous les fournisseurs. Source : Stripe, comportement de livraison

Pour une notification décrivant un changement d’état, précisez comment un message ancien sera rapproché de l’état actuel faisant autorité. Ne laissez pas une arrivée tardive rétablir silencieusement un état dépassé.

5. Tester les reprises sans produire d’effets réels indésirables

Notre recommandation : utiliser un environnement autorisé, des données synthétiques et une action de test sans conséquence métier. Préparez les résultats attendus avant l’essai :

  • Un message valide déclenche le traitement attendu dans le bon périmètre.
  • Une signature absente, incorrecte ou un contenu modifié est refusé.
  • Une livraison trop ancienne est traitée selon le contrôle de fraîcheur documenté.
  • Deux livraisons du même événement n’ajoutent pas deux fois le même effet.
  • Une panne survient avant l’enregistrement, puis après l’action mais avant la confirmation locale.
  • Deux messages arrivent dans un ordre différent de celui supposé par le traitement.
  • Une même identité présente un contenu contradictoire ou un autre périmètre.

Exemple entièrement fictif : une notification doit ouvrir un seul dossier de test. Une panne simulée intervient après sa création, avant l’enregistrement local du résultat. Lors de la reprise, le contrôle doit retrouver ce dossier et poursuivre le suivi prévu, sans créer un second dossier par défaut. Vérifiez le résultat dans le système de test destinataire, pas uniquement dans les logs du récepteur.

Conservez aussi un contrôle positif après les essais de refus. Un point d’entrée indisponible ne doit pas être confondu avec une protection qui rejette correctement les messages non conformes.

6. Rendre la reprise explicable à l’astreinte

Le compte rendu devrait relier la source, l’identité validée, les livraisons associées, les états de traitement et l’effet confirmé. Identifiez le propriétaire des erreurs non résolues, la méthode de reprise et le critère qui autorise une nouvelle tentative. Les corps et signatures conservés doivent rester dans les emplacements autorisés, avec une durée adaptée au besoin.

Rejouez les essais après une modification du proxy, de la bibliothèque, du protocole, de la gestion des secrets ou du système destinataire. Le critère de réception est concret : expliquer pourquoi un message a été accepté, quel événement il représente et pourquoi son effet a été appliqué une fois ou repris sans duplication.