J’espère que quelqu’un pourra me dire ce que je fais de mal ici.
J’ai configuré un Webhook Discourse et il fonctionne comme prévu sans Secret. J’écris ensuite une chaîne de caractères dans le Secret, puis je copie cette chaîne dans le Webhook récepteur sous forme d’en-tête, comme ceci :
X-Discourse-Event-Signature: secret_here
Cela produit l’erreur suivante dans le corps lorsque le webhook d’envoi est envoyé :
{"code":"rest_forbidden","message":"Désolé, vous n'êtes pas autorisé à faire cela.","data":{"status":401}}
Je suppose que je ne fais pas les choses correctement, alors éclairez-moi !
Je suis conscient que le secret est chiffré à l’aide de sha256, donc l’en-tête envoyé est :
X-Discourse-Event-Signature: sha256=XXX
Mais je ne suis pas sûr de ce que je dois faire de ces informations dans les en-têtes de sécurité du Webhook récepteur.
Je ne suis pas sûr si c’est juste la façon dont vous écrivez le message, mais l’en-tête réel serait
X-Discourse-Event-Signature: XXX
Vous pouvez (facultativement) l’utiliser à la réception pour valider que le webhook a bien été envoyé par Discourse. Si vous ne faites pas la vérification, une partie malveillante pourrait potentiellement usurper des événements webhook.
Mon site Web Wordpress. J’utilise un plugin Wordpress pour recevoir des Webhooks. Si je n’ajoute pas d’en-tête de sécurité (Secret), le Webhook fonctionne correctement. Le problème ne survient que lorsque j’ajoute le secret.
Des en-têtes de sécurité personnalisés peuvent être inclus dans le déclencheur de webhook entrant, mais une note importante est la façon dont WordPress peut remplacer les tirets par des traits de soulignement. Par exemple, essayer d’utiliser « x-api-key » peut nécessiter d’utiliser « x_api_key » à la place.
J’ai cependant une question connexe @RGJ . Supposons que mon secret soit « 1234 ». Dans le webhook récepteur, la valeur de X-Discourse-Event-Signature doit-elle être :
Il semble que le plugin Wordpress que vous utilisez ne puisse comparer qu’à une valeur d’en-tête statique, pas à une signature dynamique. C’est quelque chose de spécifique à Discourse.
J’ai découvert depuis que la valeur sha change à chaque fois que le webhook est envoyé, donc mettre la valeur sha dans le webhook récepteur ne fonctionnerait pas. Je penserais que cela devrait être l’exemple n°1, et comme je pense que vous suggérez (en-tête statique), le plugin devrait en fait décoder le hachage avant de générer la réponse de l’en-tête ?
En conclusion, je ne pense pas pouvoir utiliser le X-Discourse-Event-Signature haché dans ce plugin, car il n’acceptera que des valeurs statiques.
Est-il dangereux d’utiliser un webhook sans secret ? J’enverrais des événements utilisateur de mon Discourse vers mon site Web principal, en utilisant une URL non évidente telle que main-site.com/wp-json/fol/fil/532563-5312534. Je peux également ajouter des en-têtes statiques qui doivent correspondre sur le hook récepteur.
Pourriez-vous me donner un exemple d’application qui pourrait gérer un hmac dynamiquement changeant ?
La valeur est calculée par rapport à la charge utile du webhook, elle sera donc différente pour chaque requête.
C’est une question intéressante. La seule application que je connaisse est le plugin WP Discourse, mais il a été spécifiquement configuré pour gérer les webhooks de Discourse. Si l’implémentation de Discourse empêche les gens de valider les webhooks avec des secrets, peut-être que cela doit être examiné.
Je laisse les autres répondre à cela.
Si vous craignez de ne pas valider le webhook, peut-être que le plugin Incoming Webhook Triggers a un hook d’action dans son code de réception de webhook qui est déclenché avant que les données du webhook ne soient traitées. S’il en a un, il devrait être possible d’écrire une fonction qui s’y accroche, vérifie si les données sont pour un webhook Discourse, puis valide le secret avec quelque chose comme le code que j’ai lié dans mon message précédent.
J’étais curieux, alors j’ai examiné cela un peu. Je ne suis pas sûr des applications qui sont configurées pour gérer la réception d’une signature HMAC qui change dynamiquement, mais l’authentification des requêtes webhook avec une signature HMAC calculée par rapport à la charge utile est une pratique assez standard pour les applications qui envoient des webhooks. Par exemple, GitHub, Stripe et Shopify utilisent tous cette méthode.
Il existe également un certain nombre d’applications populaires qui utilisent la méthode du jeton secret pour authentifier les webhooks. Par exemple (en 2021), Mailchimp, Trello, Slack et Discord utilisaient tous cette approche. Il semble que Slack utilise toujours cette méthode : Slack developer FAQ | Slack Developer Docs. Je peux comprendre comment cela rendrait les choses plus faciles pour l’application qui reçoit le webhook.
Je suppose qu’il y a un compromis entre la sécurité et la commodité pour décider quelle méthode l’application d’envoi utilisera. Ma préoccupation concernant la méthode de signature HMAC de Discourse est qu’elle pourrait amener les gens à configurer des webhooks sans clés secrètes afin de contourner la difficulté de gérer les signatures HMAC changeantes. Par exemple, il existe quelques références sur Meta pour l’envoi de webhooks Discourse à Zapier sans aucune mention de la façon de valider la signature sur Zapier. (Il devrait être techniquement possible de valider les signatures sur Zapier cependant. Je ne suis pas configuré pour tester cela pour le moment.)
Je suis tout à fait d’accord avec cela. Peut-être est-ce quelque chose que les développeurs peuvent explorer - une méthode plus simple et plus compatible pour sécuriser les données des webhooks.
De plus, je ne suis pas si sûr que Zapier soit capable de valider la signature.
La fonctionnalité de secret de webhook est implémentée conformément à ceci :
Il semble que le logiciel que vous souhaitez ne prenne pas en charge cette fonctionnalité de communication de sécurité standard, mais vous pouvez toujours utiliser les webhooks Discourse sans elle.
Il n’est pas prévu d’ajouter un en-tête fixe avec un secret partagé, car la valeur de sécurité de celui-ci est discutable. Cependant, si vous en avez besoin, cela devrait être réalisable dans un plugin.