Au programme aujourdâhui :
Sécuriser vos Webhooks en Ruby on Rails par François
Temps de lecture : 5 minutes
Hello les petits Biscuits !
Bienvenue sur la 28Úme édition de Ruby Biscuit.
Vous ĂȘtes maintenant 540 abonnĂ©s đ„ł
Maintenant Ruby biscuit, câest aussi votre meilleur alliĂ© pour recruter des devs Ruby !
Si vous nâavez pas encore rejoint le club, RDV sur https://recrutement.rubybiscuit.fr
Bonne lecture.
Sécuriser vos Webhooks en Ruby on Rails
Dans le dĂ©veloppement dâapplications web, les webhooks sont un mĂ©canisme courant pour recevoir des notifications externes sur des Ă©vĂ©nements spĂ©cifiques. Par exemple, une application peut recevoir un webhook de service tiers de signature Ă©lectronique pour l'informer lorsqu'un document a Ă©tĂ© signĂ©. Cependant, sans mesures de sĂ©curitĂ© appropriĂ©es, les webhooks peuvent ĂȘtre exploitĂ©s, exposant ainsi votre application Ă des risques de sĂ©curitĂ©.
Dans cet article, nous allons passer en revue un certain nombre de techniques disponibles pour sĂ©curiser les webhooks. Ensuite nous verrons une mise en pratique avec les webhooks de Dropbox Sign. Nous verrons comment mettre en pratique trois techniques pour sĂ©curiser les webhooks dans une application Ruby on Rails : la vĂ©rification des adresses IP, l'utilisation d'un secret partagĂ© (HMAC), et les strong parameters pour filtrer les donnĂ©es entrantes. Ces pratiques garantiront que seules les requĂȘtes authentiques et sĂ©curisĂ©es seront traitĂ©es par votre application. Enfin nous verrons comment tester ces 3 mesures de sĂ©curitĂ© avec Rspec.
Comprendre les Méthodes de Sécurisation des Webhooks
Avant d'entrer dans l'implémentation, voyons quelques méthodes disponibles pour la sécurisation des webhooks :
Appeler le service : MĂȘme lorsqu'ils sont sĂ©curisĂ©s, les webhooks ne sont pas adaptĂ©s pour transmettre des informations sensibles. Une façon de sĂ©curisĂ© lâutilisation des webhooks est de seulement les utiliser pour ĂȘtre informĂ© dâun Ă©vĂ©nement pour une ressource et ensuite dâappeler le service externe via une API pour connaitre lâĂ©tat de cette ressource. (voir exemple dans la section suivante)
VĂ©rification des IPs : Restreindre lâaccĂšs aux webhooks uniquement Ă certaines adresses IP. Cela permet de sâassurer que les requĂȘtes proviennent dâune source autorisĂ©e, comme un service tiers de confiance (Dropbox Sign dans cet exemple).
VĂ©rification du Secret (HMAC) : Un secret partagĂ© ou un HMAC (Hash-based Message Authentication Code) permet de valider que la requĂȘte n'a pas Ă©tĂ© altĂ©rĂ©e et qu'elle provient bien de la source prĂ©vue.
Strong Parameters : Filtrer les données entrantes pour s'assurer qu'elles correspondent aux attentes et éviter les injections de données non désirées ou malveillantes.
Timestamp pour prĂ©venir les attaques par rejeu (Replay Attacks) : En incluant un timestamp dans la requĂȘte du webhook, vous pouvez vĂ©rifier que l'Ă©vĂ©nement n'est pas ancien et qu'il n'a pas Ă©tĂ© rejouĂ©. Si l'horodatage dĂ©passe un certain seuil (par exemple, 5 minutes), la requĂȘte est rejetĂ©e.
Chiffrement des donnĂ©es envoyĂ©es : Chiffrer les donnĂ©es transmises via les webhooks, notamment lorsqu'elles contiennent des informations sensibles, garantit que seules les parties autorisĂ©es peuvent les lire. Cela peut ĂȘtre rĂ©alisĂ© avec HTTPS ou en chiffrant manuellement les payloads.
Utiliser HTTPS et la vĂ©rification SSL : GitHub vĂ©rifie les certificats SSL lors de la transmission des webhooks et il est fortement recommandĂ© de laisser cette vĂ©rification activĂ©e. Cela attenue les risques dâĂ©coutes clandestines (eavesdropping) et les attaques de l'intercepteur (man-in-the-middle MITM), oĂč un attaquant peut intercepter et modifier la donnĂ©e avant de la transmettre.
Voir plus sur Introduction to Webhook Security - Docs
Appeler le service tiers aprĂšs reception du webhook
Comme mentionnĂ© dans la section prĂ©cĂ©dente, les webhooks ne sont pas la mĂ©thode de communication la plus sĂ©curisĂ©e et les donnĂ©es transfĂ©rĂ©es sont sensibles (exemple les donnĂ©es bancaires). Par consĂ©quent, certains fournisseurs de service comme Swan n'utilisent pas de webhooks pour envoyer des informations sensibles qui nĂ©cessitent une authentification pour ĂȘtre affichĂ©es. Le webhook inclut uniquement une notification indiquant qu'un Ă©vĂ©nement s'est produit et une id de ressource afin de pouvoir la retrouver. Il faut ensuite utiliser l'API pour obtenir les informations. On peut visualiser cela dans le graphique ci dessous :
Sécurisation grùce aux fonctionnalités fournies
Tous les fournisseurs de service tiers mettant Ă disposition des webhooks ne fournissent pas de mesures de sĂ©curitĂ©, mais beaucoup le font. Les contrĂŽles de sĂ©curitĂ© mis Ă disposition par le fournisseur de webhook permettent de valider l'authenticitĂ© des Ă©changes et Ă empĂȘcher leur falsification. Cependant, la plupart des fournisseurs n'exigent pas de la part des applications consommants leur service qu'elles utilisent la sĂ©curitĂ© qu'ils fournissent. C'est aux dĂ©veloppeurs de lire la documentation du webhook du fournisseur pour savoir quelles options sont disponibles, les comprendre, puis les mettre en Ćuvre.
Implémentation en Ruby on Rails
Dans cet exemple, nous allons implémenter un contrÎleur webhook pour Dropbox Sign, avec les trois couches de sécurité suivantes : la vérification d'IP, le HMAC, et les strong parameters.
Code du ContrĂŽleur
Explications :
Vérification d'IP : Le filtre
verify_ip_address
s'assure que la requĂȘte provient bien des IPs autorisĂ©es dĂ©finies dans la constanteALLOWED_IPS
.Vérification HMAC : La méthode
verify_secret
utilise un secret (clĂ© API) pour vĂ©rifier la signature de la requĂȘte. Cela garantit que la requĂȘte provient bien de Dropbox Sign et qu'elle n'a pas Ă©tĂ© modifiĂ©e.Strong Parameters : Nous utilisons
webhook_payload
pour filtrer et limiter les donnĂ©es aux seuls paramĂštres attendus, ce qui empĂȘche l'injection de donnĂ©es non dĂ©sirĂ©es.
Voir la documentation de Dropbox Sign pour plus de détail : Events Walkthrough | Dropbox Sign for Developers
Rspec tests
Il est important de tester les vĂ©rifications, notamment pour sâassurer que seules les IPs autorisĂ©es et les requĂȘtes valides sont acceptĂ©es.
Voici un exemple de tests :
Ce que fait ce test :
Il simule lorsque tout va bien.
Il simule des requĂȘtes venant dâune IP autorisĂ©e et dâune IP non autorisĂ©e.
Si l'IP est autorisée, le webhook est traité avec succÚs.
Si l'IP n'est pas autorisĂ©e, une rĂ©ponse "not found" est renvoyĂ©e, empĂȘchant la requĂȘte d'ĂȘtre traitĂ©e.
Il simule des requĂȘtes avec un secret valide et invalide.
Si le secret est valide, le webhook est traité avec succÚs.
Si le secret nâest pas valide, une rĂ©ponse "not found" est renvoyĂ©e, empĂȘchant la requĂȘte d'ĂȘtre traitĂ©e.
Conclusion
La sĂ©curisation des webhooks est cruciale pour protĂ©ger vos applications contre les attaques et les abus. En combinant la vĂ©rification des adresses IP, lâutilisation de secrets partagĂ©s et le filtrage des paramĂštres, vous vous assurez que seules les requĂȘtes authentiques et sĂ»res sont traitĂ©es par votre application.
Repo associé : https://github.com/francoisedumas/basic_app_esbuild
Pour aller plus loin
Vous trouverez sur ma chaine YouTube de nombreux sujet technique que jâexplore et explique. Kokori Kodo
â François