Comment ne pas stocker les mots de passe dans une base de données
Note préalable : si cet article est une étude de cas concernant une application réelle, toutes les variables ont été modifiées pour des raisons de confidentialité.
L’imaginaire des développeurs
Lors d’un test d’intrusion dans le cadre de mon activité professionnelle, j’ai rencontré dans une application SaaS une bizarrerie qui s’est ensuite avérée être le point de départ d'une mini cryptanalyse très intéressante.
Je procédais tranquillement à ce test d’intrusion lorsque j’ai constaté que la fonctionnalité de récupération de mot de passe m’envoyait en clair mon mot de passe par e-mail. J’ai donc décidé de creuser cette question lorsque j’ai constaté plus loin qu’un administrateur de l’application pouvait faire des requêtes sur la base de données pour afficher des informations aux autres utilisateurs.
Sans surprise, mon compte administrateur de l’application (attention à ne pas le confondre avec l’administrateur système qui a des droits plus élevés) m’a permis à travers quelques requêtes détournées d’obtenir la table des utilisateurs.
Je me retrouve alors avec une liste dans les champs mot de passe de la forme suivante :
- FAjBgCgDvEqFhGaHIJK
- 1AsBeCiDpEmFqGnHaIoJK
- 0A1BCCuDpEwFjGlHIJK
(+ quelques milliers de lignes)
Premier constat : ce ne sont pas les mots de passe « en clair ». Je fais donc un premier tour de la forme des principaux algorithmes de hashage sans rien trouver. L’éditeur m’indique qu’ils ne sont pas chiffrés ou hashés. De plus un algorithme de hashage donne en général une empreinte de taille constante quelle que soit l’entrée donnée.
Deuxième constat : TOUS les mots de passe ont un caractère sur 2 qui est identique d’une ligne à l’autre et se terminent par les mêmes caractères dans les cas les plus courts. Je retire donc ces caractères car ils sont constants sur mes quelques milliers de lignes.
Pour les mots de passe ci-dessus on obtient en retirant les lettres constantes :
- Fjggvqha
- 1seipmqnao
- 01Cupwjl
Sans grande conviction, je teste une attaque par clair connu car je peux modifier mon propre mot de passe et visualiser l’empreinte résultante.
Note : une attaque par clair connu permet d’obtenir des informations à propos de la méthode de chiffrement ou de la clé de déchiffrement selon les cas. Elle consiste à obtenir des informations par la connaissance de la version « en clair » de tout ou une partie du chiffré. Évidemment, même il s’agit d’une vulnérabilité présente dans de nombreux systèmes de chiffrement, les méthodes standards aujourd’hui n’y sont en général pas sensibles, qui peut dans certains cas (clé courte) se révéler très dangereuse.
Je modifie mon mot de passe pour avoir successivement les valeurs suivantes (en effet, la longueur du mot de passe est limitée) :
- abcdefghijk
- lmnopqrstu
- vwxyzABCD
- EFGHIJKLMN
- OPQRSTUVWX
- YZ0123456789
Et surprise ! Non seulement les répétitions dans le clair se répercutent dans le « chiffré » mais en plus ces permutations sont constantes d’un utilisateur à l’autre !
Et j’obtiens la table de correspondance suivante (pour décoder un caractère du haut le faire correspondre à un caractère du bas) :
original = “YNILARTECMBHWUDPFKZGSJOXQVjanvierznbkdocqdmhgplyvxuf4815309672”
decoded = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789”
Plus qu’à faire un script et j’ai les mots de passe de tous les utilisateurs en clair en quelques secondes.
Conclusion
Le stockage « en clair » des mots de passe dans la base de données est une mauvaise pratique. En effet, une vulnérabilité permettant d’obtenir directement les informations stockées par l’application laisse alors la possibilité d’obtenir l’ensemble des mots de passe. Traditionnellement on utilise un système à partir de fonctions de hashage et de sels pour obtenir deux empreintes différentes pour un même mot de passe. Il est aussi possible de chiffrer de manière réversible les mots de passe pour pouvoir les obtenir en clair mais c’est plus rare et nettement plus difficile à mettre en place de manière sécurisée.
Dans ce cas on peut reconnaître l’honnêteté de l’éditeur qui a déclaré ne pas stocker ses mots de passe de manière chiffrée. Ceci laisse supposer que cette technique de « chiffrement » est destinée à cacher les mots de passe à un administrateur système honnête. On notera toutefois l’imagination du développeur qui aura intégré un mot dans la table de correspondance.
Au final cette technique est probablement plus difficile à mettre en place qu’un hashage des mots de passe à l’aide d’un sel. De plus la mise en place d’un mécanisme de récupération de mot de passe qui repose sur un lien aléatoire de réinitialisation plutôt que l’envoi en clair du mot de passe reste abordable.
Billet publié avec l’aimable autorisation d’I-Tracing (www.i-tracing.com)