J’en cause ici parce que j’ai l’impression que ce blog est assez lu par ceux qui geekent autour et avec Dotclear et donc voilà la question que je me pose en ce moment.
Vous n’êtes pas sans savoir que la mise à jour de la structure de la base n’est pas assurée pour ceux qui utilisent QSLite comme système de stockage des données. J’ai un peu regardé la littérature à ce sujet, et à part produire pas mal de code pour gérer ça au mieux, il n’y a pas grand chose de simple, ne serait-ce que pour changer la longueur d’un champ dans une table[1].
Or, avec l’idée de renforcer la sécurité des mots de passe stockés dans la base, j’aimerais pouvoir permettre l’usage d’autres algorithmes que les seuls sha1 et md5. Seulement l’usage de certains algorithmes supportés par PHP produit un chiffrement dont la longueur peut être supérieure aux actuels 40 caractères actuellement prévus dans la base[2].
Par exemple, les algorithmes sha512 ou whirlpool produisent un résultat de 128 caractères de long. Au passage, voilà comment afficher la liste des algorithmes supportés par votre installation et les longueurs résultantes :
$algos = hash_algos(); foreach ($algos as $algo) { $code = crypt::hmac(DC_MASTER_KEY,'mot de passe',$algo); echo '- '.$algo.' → '.strlen($code).'<br />'; }
Ce qui donne, sur mon installation locale en PHP7, le résultat suivant :
md2 → 32 md4 → 32 md5 → 32 sha1 → 40 sha224 → 56 sha256 → 64 sha384 → 96 sha512 → 128 ripemd128 → 32 ripemd160 → 40 ripemd256 → 64 ripemd320 → 80 whirlpool → 128 tiger128,3 → 32 tiger160,3 → 40 tiger192,3 → 48 tiger128,4 → 32 tiger160,4 → 40 tiger192,4 → 48 snefru → 64 snefru256 → 64 gost → 64 gost-crypto → 64 adler32 → 8 crc32 → 8 crc32b → 8 fnv132 → 8 fnv1a32 → 8 fnv164 → 16 fnv1a64 → 16 joaat → 8 haval128,3 → 32 haval160,3 → 40 haval192,3 → 48 haval224,3 → 56 haval256,3 → 64 haval128,4 → 32 haval160,4 → 40 haval192,4 → 48 haval224,4 → 56 haval256,4 → 64 haval128,5 → 32 haval160,5 → 40 haval192,5 → 48 haval224,5 → 56 haval256,5 → 64
J’ai fait les modifications nécessaires côté Clearbricks pour permettre l’utilisation d’un autre algorithme, maintenant je suis devant le choix suivant pour continuer côté Dotclear :
- Je ne touche à rien côté longueur du champ qui stocke le mot de passe et je me limite aux 40 premiers caractères du mot de passe chiffré fourni par Clearbricks. L’avantage est que ça ne change pas côté structure de la base, par contre ça réduit forcément la sécurité.
- J’agrandis le champ à 255 caractères, histoire de voir venir, mais je force les utilisateurs de SQLite à mettre à jour de manière fastidieuse leurs installations.
Pour résumer, est-ce que ça vaut le coup de ne pas toucher à la structure et permettre une mise à jour « douce », ou est-ce que l’usage de SQLite est suffisamment anecdotique pour passer outre, ou s’il ne l’est pas [anecdotique], développer ce qu’il faut pour assurer quoi qu’il arrive une mise à jour automatique des bases SQLite ?
Autre interrogation :
Sachant que l’algorithme qui a servi à chiffrer le mot de passe n’est pas stocké dans la base, et heureusement d’ailleurs, il est compliqué de mettre en place un système automatique de conversion du chiffrement de l’ancien au nouveau si celui-ci est modifié dans la configuration.
On sera quoi qu’il en soit obligé de passer par la procédure de récupération de mot de passe pour pouvoir l’appliquer et se connecter ensuite.
Du coup, est-ce que renforcer la sécurité pour la prochaine version 2.10 de Dotclear vaut réellement que j’y passe un peu de temps ? J’aurais tendance à dire que oui, mais je ne suis pas (encore) le seul utilisateur de Dotclear sur la planète.
Bref, j’ai pensé que la première étape était d’essayer de recenser les utilisateurs actuels de SQLite sur cette planète, sachant que les blogs des différentes plateformes comme Free ou Gandi sont sur PostgreSQL (ou peut-être sur MySQL pour les plus petites d’entre elles) :
Chers utilisateurs/administrateurs de blog #Dotclear, vous avez choisi quoi comme gestionnaire de base de données :
— Franck Paul (@franckpaul) 24 mars 2016
Je vois que j’ai déjà quelques réponses[3] à mon enquête, c’est cool \o/
Maintenant vous pouvez aussi me répondre dans les commentaires de ce billet si vous préférez !
Notes
[1] À part renommer une table ou ajouter un champ à une table, la commande ALTER TABLE
de SQLite ne permet rien.
[2] L’algorithme md5 produit un résultat de 32 caractères de long, sha1 en produit un qui fait 40.
[3] À l’heure où j’écris ce billet, 4 utilisent MySQL, 2 PostgreSQL et 2 ne savent pas, et s’ils ne savent pas je pense que je peux raisonnablement estimer qu’ils n’utilisent pas SQLite qui est un peu plus particulier.
1 De mirovinben -
2 De Cunégonde -
Comment veux tu que je le sache ?
3 De Franck -
mirovinben « … il ne faut rien casse. », euh ça s’est l’idéal, mais l’omelette, les œufs, tu vois ? :-)
Cunégonde si tu ne sais pas c’est que tu n’utilises probablement pas SQLite :-)
4 De Luc -
Quand j’étais chez Free : PostgreSQL
Depuis : MySQL
Voilà, voilà! :-)
5 De Franck -
Merci Luc !
6 De Diablotin -
Je n’utilise pas Dotclear : c’est mal ? ;-) ! En fait, j’ai opté pour une solution de facilité, à une époque ou Dotclear semblait un peu en déshérence.
Par contre, je sais que j’utilise MySQL et PHP 5.6
7 De Franck -
Diablotin non, c’est pas mal d’utiliser autre chose que Dotclear :-)
8 De Tristan -
Diablotin : n’écoute pas Franck : utiliser autre chose que Dotclear, c’est mal ! ;-)
—Tristan (MySQL, au fait)
9 De Franck -
Merci Tristan pour ton indéfectible soutien \o/
10 De mat -
Niveau passwords, il faut absolument oublier les algos de hash genre md5, sha1, etc. Ils sont brute-forcés de manière triviale de nos jours, même avec un salt.
La seule vraie bonne manière sécurisée de faire, c’est d’utiliser des algos faits pour: bcrypt, PBKDF2, scrypt, argon2. PHP implémente ça de base avec password_hash(), qui a le bon goût de gérer lui-même le salt (source classique de faiblesse si il est mal généré). Sinon, crypt() le fait aussi mais c’est un peu plus manuel, il faut fournir le salt (bien regarder les histoires de génération aléatoire, ne pas utiliser juste rand()/mt_rand())
J’ai écrit un article sur le sujet (quelques approximations, un peu vieux, mais suffisant comme intro) http://letrainde13h37.fr/22/le-stoc…
Plus récent en anglais: https://paragonie.com/blog/2016/02/…
11 De Franck -
C’est vrai mat qu’on pourrait largement mieux faire en ce domaine. Cela dit, question attaque par btute force, on a implémenté un délai variable (entre 2 et 5 secondes) entre deux essais, largement acceptable par un utilisateur lambda et qui ralentirait pas mal une attaque.
Maintenant ce n’est pas la panacée, je vais jeter un œil aux articles que tu cites, merci !
12 De mat -
Le delai artificiel c’est bien, mais ça ne suffit pas: pour protéger efficacement des mots de passe, il faut partir du principe que l’attaquant a déjà accès à la base de donnés. L’idée n’est pas seulement de protéger ton application, mais les mots de passe eux-mêmes, vu que les utilisateurs ont tendance à re-utiliser les mêmes partout.
C’est la que les algos que j’ai cités sont adaptés au problème : ils sont conçus pour être un peu lents de base, et rendent un brute-force très difficile, même avec une copie de la base.
13 De Franck -
Compris, vais creuser ça pour le futur de Dotclear, merci pour l’éclairage.
14 De daffyb -
PostgreSQL pour un blog perso (OVH)
MySQL pour un blog pro (WAMP intranet)