🍪 🗺️ Protège ton back-office avec un préfixe unique
Si tu utilises Active Admin, Rails Admin, Administrate ou si tout simplement si tu as un back-office sur ton application Rails alors il faut le rendre secret. Parce que, oui, utiliser la route /admin pour ton back-office, c’est presque du même niveau qu’utiliser password comme mot de passe.
Au programme :
Pourquoi rendre son back-office secret
Tests unitaires
Préfixer des routes
authenticate
vsauthenticated
Bonjour et bienvenue sur la 5ème édition de Ruby Biscuit.
Vous êtes maintenant 77 abonnés 🥳 Si vous n’êtes pas déjà inscrit :
Pourquoi rendre son back-office secret
Il y a quelques années un client nous à demandé s’il était possible que l’on change l’URL de son back-office pour ne pas y accéder aussi simplement qu’avec /admin
. En faisant ce changement nous nous sommes rendus compte que l’idée était bonne et qu’elle permettait de manière très simple de sécuriser davantage nos plateformes. En effet nous ne souhaitons pas que n’importe qui puisse atterrir sur la page de connexion d’un back-office. La nouvelle règle est donc : toutes les routes des back-offices seront préfixées par un mot “atypique” qui doit être quasiment introuvable pour quiconque n’aurait pas besoin d’y avoir accès.
Résultat : Lors d'un récent audit de sécurité, notre back-office n'a pas été détecté par des tests d'intrusion en boite noire et boite grise 🕵️
C’est plutôt pratique pour éviter une infiltration par la porte arrière 🚪
Je vais vous montrer les changements réalisés sur nos plateformes et nos choix d’implémentation.
Voici à quoi ressemble notre fichier config/routes.rb
actuellement :
Nous avons les routes de Devise pour notre admin, les routes Active Admin et aussi une route pour qu’un administrateur connecté puisse accéder au tableau de bord de Sidekiq.
Tests unitaires
Pour l’exemple je pars d’une application Rails avec Devise, Active Admin et Rspec.
Comme le veut la bonne pratique et afin de documenter et guider notre implémentation, commençons par écrire nos tests.
Je veux m’assurer que la page de connexion du back-office soit introuvable avec l’URL /admin
mais qu’en revanche tout fonctionne avec mon préfixe.
Nous choisirons le préfixe “rubyscuit” pour l’exemple 😉
Je souhaite également que mon tableau de bord Sidekiq ne me redirige pas vers la page de connexion du back-office lorsqu’aucun administrateur n’est connecté. Nous reviendrons sur cette partie plus en détails. En attendant voici les tests :
Préfixer des routes
L’idée ici est de donc de préfixer les routes Active Admin et Devise du back-office, pour qu’elles soient introuvables.
Pour cela nous avons décidé de préfixer nos routes. Nous aurions pu choisir de les modifier, mais nous avons préféré garder la notion d’admin.
Pour préfixer un groupe de route avec Rails il existe différentes options dont les namespaces et les scopes.
Il est important de comprendre la différence car elle affecte la structure de notre application.
Le namespace va préfixer le chemin de l’URL et va chercher à localiser un contrôleur sous un module nommé de la même manière que le préfixe choisi.
Avec le code suivant dans config/routes.rb
Voici un exemple des routes que l’on obtient :
Nos routes ont été préfixées par “rubyscuit” dans le chemin URI et Rails s'attend à ce que nos controllers (excepté ceux de Devise) soient dans un module du même nom : Rubyscuit::Admin::Dashboard#index
.
Le scope est différent car il n’affecte pas le chemin des ressources.
Voici les routes générées :
Comme on peut le voir /rubyscuit
a été ajouté comme préfixe, mais nos contrôleurs n'ont pas besoin d'être dans un module.
Nous avons donc fait le choix d’utiliser les scopes pour ne pas surcharger l’application avec des modules non nécessaires. Notre but étant uniquement que le chemin du back-office ne se devine pas. C’est maintenant chose faite.
Grace à ce scope, mon URL pour la page de connexion est maintenant : /rubyscuit/admin/login
et mis à part vous, personne ne le devinera !
authenticate
vs authenticated
Ce n’est pas terminé ! Rappelez-vous que nous avons cette route /sidekiq
pour accéder au tableau de bord de Sidekiq lorsque nous sommes connectés en tant qu’administrateur.
Cette route fréquemment utilisée sur les applications Rails dotées de Sidekiq nous pose un souci : lorsqu’une personne non connectée essaye d’y accéder, elle renvoie automatiquement vers la page de connexion du back-office. C’est au helper authenticate
de Devise que nous devons ce comportement.
Toutes les personnes essayant d’accéder au tableau de bord, seront en mesure d’atterrir sur la page de connexion du back-office et donc de découvrir l’URL préfixée.
La première solution pourrait être de mettre cette route dans notre scope “rubyscuit”.
Chez Capsens certains le font, d’autres non. Ceux qui ne le font pas considèrent que malgré le fait que le tableau de bord ne soit accessible que par un administrateur, il n’est pas à mélanger aux routes de notre back-office, mais aussi par envie de garder cette route simple /sidekiq
. Libre à vous de choisir votre stratégie.
En partant du principe que nous ne souhaitons pas mettre cette route dans notre scope, nous allons simplement changer le helper authenticate
par un autre : authenticated
.
La différence est simple, authenticated
permet d’accéder à une route en fonction de l'authentification de notre administrateur. En d’autres termes : tant qu’il n’y a pas d’administrateur, il n’y pas a de route. En essayant d’y accéder nous ne serons plus redirigés mais nous tomberons sur une 404.
Les helpers Devise en question
Version finale de nos routes :
Maintenant, plus aucune chance de trouver le back-office !
Pour découvrir des nouveaux tips Ruby on Rails tous les mercredis à 16h, ne cherche plus, tu es au bon endroit !
Rendez-vous la semaine prochaine 😉
Mélanie