Fonction js sha256 défaillante #5059

Closed
opened 6 months ago by emile · 5 comments
emile commented 6 months ago

Version spip: 4.0.4

Il semblerait que la fonction JS inclue dans la page de login qui calcule le sha256 du mot de passe est défaillante.
En effet, Spip nous refuse l'accès à l'interface d'admin après un changement du mot de passe contenant un certain nombre de caractères.

Pour rappel la page de login calcule une version hashée du mot de passe avant de la renvoyer au server (probablement pour éviter d'envoyer le mot de passe en clair, à une époque ou le https n'était pas aussi répandu qu'aujourd'hui).

Pour reproduire voici un petit bout de code JS à lancer dans un repertoire spip:

var fs = require('fs');
eval(fs.readFileSync('prive/javascript/sha256.js')+'');
console.log(hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX'));
console.log(hex_sha256('18280887846213add5aa12c6.82484384bkfWyizpu9Pl8TK91NnPkQEntgIV'));

Ce code inclu la fonction sha256 appelée dans la page de login. Il demande ensuite à hasher deux mots de passe (on reconnait ici la concatenation alea+password). Le résultat du premier appel est faux, le deuxième est bon. Vous pouvez vérifier avec la commande sha256sum sous linux:

echo -n '13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX' | sha256sum
echo -n '18280887846213add5aa12c6.82484384bkfWyizpu9Pl8TK91NnPkQEntgIV' | sha256sum

Vous pouvez aussi reproduire ce bug en essayant de mettre un mot de passe de 25 caractères alphanumériques dans un compte spip.

J'imagine que pour corriger ce bug il y a deux possibilités:

  • Éstimer que toutes les interfaces de login sont en https et arrêter de hasher le mot de passe avant de l'envoyer au serveur.
  • Changer de méthode pour calculer le hash (peut-être trouver une bibliothèque plus récente).
Version spip: 4.0.4 Il semblerait que la fonction JS inclue dans la page de login qui calcule le sha256 du mot de passe est défaillante. En effet, Spip nous refuse l'accès à l'interface d'admin après un changement du mot de passe contenant un certain nombre de caractères. Pour rappel la page de login calcule une version hashée du mot de passe avant de la renvoyer au server (probablement pour éviter d'envoyer le mot de passe en clair, à une époque ou le https n'était pas aussi répandu qu'aujourd'hui). Pour reproduire voici un petit bout de code JS à lancer dans un repertoire spip: ``` var fs = require('fs'); eval(fs.readFileSync('prive/javascript/sha256.js')+''); console.log(hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX')); console.log(hex_sha256('18280887846213add5aa12c6.82484384bkfWyizpu9Pl8TK91NnPkQEntgIV')); ``` Ce code inclu la fonction sha256 appelée dans la page de login. Il demande ensuite à hasher deux mots de passe (on reconnait ici la concatenation alea+password). Le résultat du premier appel est faux, le deuxième est bon. Vous pouvez vérifier avec la commande sha256sum sous linux: ``` echo -n '13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX' | sha256sum echo -n '18280887846213add5aa12c6.82484384bkfWyizpu9Pl8TK91NnPkQEntgIV' | sha256sum ``` Vous pouvez aussi reproduire ce bug en essayant de mettre un mot de passe de 25 caractères alphanumériques dans un compte spip. J'imagine que pour corriger ce bug il y a deux possibilités: * Éstimer que toutes les interfaces de login sont en https et arrêter de hasher le mot de passe avant de l'envoyer au serveur. * Changer de méthode pour calculer le hash (peut-être trouver une bibliothèque plus récente).
Owner

En js sur la page de login je confirme le problème sur l'exemple donné

hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX')
"47327e3fe3e25cb1967098d863a3044856d2f37b0fd0c04c656764b1bd172789"

et en PHP

php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX")."\n");
f080242c98e5e351ba9c8ba20d947b89aa824ce1e0cd362322885f57662b0a96

Mais à côté de ça, spontanément je n'ai pas trouvé d'exemple qui foirait sur la base de la longueur

php > echo(hash('sha256',"123456789012345678901234")."\n");
05ae4505ae2b3f1bdc1f54a7e6b2669c3fcd3d89f4d0b55a25cbf2da29b9fcf1
js > hex_sha256('123456789012345678901234')
"05ae4505ae2b3f1bdc1f54a7e6b2669c3fcd3d89f4d0b55a25cbf2da29b9fcf1"

php > echo(hash('sha256',"1234567890123456789012345")."\n");
f2543ffdb4aff9265ad0337d3c26e5fec9ca78404e180a8a31ed9aed1520dcb6
js > hex_sha256('1234567890123456789012345')
"f2543ffdb4aff9265ad0337d3c26e5fec9ca78404e180a8a31ed9aed1520dcb6"

php > echo(hash('sha256',"12345678901234567890123456")."\n");
5adcb5971681274f04187f2ebb0d69e09df67c8fc23ea13ee7b09c3d59ff5582
js > hex_sha256('12345678901234567890123456')
"5adcb5971681274f04187f2ebb0d69e09df67c8fc23ea13ee7b09c3d59ff5582"


php > echo(hash('sha256',"123456789012345678901234567")."\n");
bd671f60435a3b99d45bbb90abcbe4aa5336500bd060c986cce4229f7d46ff3a
js > hex_sha256('123456789012345678901234567')
"bd671f60435a3b99d45bbb90abcbe4aa5336500bd060c986cce4229f7d46ff3a"


php > echo(hash('sha256',"123456789012345678901234567a")."\n");
92efc698936bdc2751f07d1e96c7674b35d3a0bd55e4a9b56139714849b0e9ae
js > hex_sha256('123456789012345678901234567a')
"92efc698936bdc2751f07d1e96c7674b35d3a0bd55e4a9b56139714849b0e9ae"

php > echo(hash('sha256',"123456789012345678901234567890")."\n");
f54e5c8f810648e7638d25eb7ed6d24b7e5999d588e88826f2aa837d2ee52ecd
js > hex_sha256('123456789012345678901234567890')
"f54e5c8f810648e7638d25eb7ed6d24b7e5999d588e88826f2aa837d2ee52ecd"

php > echo(hash('sha256',"12345678901234567890123456789012")."\n");
e1b85b27d6bcb05846c18e6a48f118e89f0c0587140de9fb3359f8370d0dba08
js > hex_sha256('12345678901234567890123456789012')
"e1b85b27d6bcb05846c18e6a48f118e89f0c0587140de9fb3359f8370d0dba08"

php > echo(hash('sha256',"123456789012345678901234567890123")."\n");
39bf8cc93fbdc84df4f7e3bb3f168b04089abb47631a16852aad5a1492c0248f
js > hex_sha256('123456789012345678901234567890123')
"39bf8cc93fbdc84df4f7e3bb3f168b04089abb47631a16852aad5a1492c0248f"

php > echo(hash('sha256',"1234567890123456789012345678901234567890")."\n");
a4ebdd541454b84cc670c9f1f5508baf67ffd3fe59b883267808781f992a0b1d
js > hex_sha256('1234567890123456789012345678901234567890')
"a4ebdd541454b84cc670c9f1f5508baf67ffd3fe59b883267808781f992a0b1d"

php > echo(hash('sha256',"1234567890123456789012345678901234567890az")."\n");
4590c143ccf5db098251480a8c0fa7eb2db1b90e2b6e7f05cb84dbf752ee68a0
js > hex_sha256('1234567890123456789012345678901234567890az')
"4590c143ccf5db098251480a8c0fa7eb2db1b90e2b6e7f05cb84dbf752ee68a0"

php > echo(hash('sha256',"1234567890123456789012345678901234567890az.")."\n");
5bc552af4b1563567c5505a582e5906e1e62d585054998246fd515bc2895cec6
js > hex_sha256('1234567890123456789012345678901234567890az.')
"5bc552af4b1563567c5505a582e5906e1e62d585054998246fd515bc2895cec6"

php > echo(hash('sha256',"1234567890123456789012345678901234567890az.01234567890")."\n");
5ac86957fe2dc32d5ccd406a225f4be6b25b3ec0bbeec34b1d913de2977b3329
js > hex_sha256('1234567890123456789012345678901234567890az.01234567890')
"5ac86957fe2dc32d5ccd406a225f4be6b25b3ec0bbeec34b1d913de2977b3329"

php > echo(hash('sha256',"123456789012345678901234567890123456789012345678901234567890")."\n");
decc538c077786966ac863b5532c4027b8587ff40f6e3103379af62b44eae44d
js > hex_sha256('123456789012345678901234567890123456789012345678901234567890')
"decc538c077786966ac863b5532c4027b8587ff40f6e3103379af62b44eae44d"

php > echo(hash('sha256',"1234567890123456789012345678901234567890123456789012345678901234567890")."\n");
4d27a733bfffd740e782bdeb0e617de620e6836826b77445dbbdeda610292bdf
js > hex_sha256('1234567890123456789012345678901234567890123456789012345678901234567890')
"4d27a733bfffd740e782bdeb0e617de620e6836826b77445dbbdeda610292bdf"

php > echo(hash('sha256',"123456789012345678901234.5678901234567890123456789012345678901234567890")."\n");
f92db7932a987c82968486e98cd3ef076b135d38f1100a5ea893fcae4e402732
js > hex_sha256('123456789012345678901234.5678901234567890123456789012345678901234567890')
"f92db7932a987c82968486e98cd3ef076b135d38f1100a5ea893fcae4e402732"

En js sur la page de login je confirme le problème sur l'exemple donné ``` hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX') "47327e3fe3e25cb1967098d863a3044856d2f37b0fd0c04c656764b1bd172789" ``` et en PHP ``` php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX")."\n"); f080242c98e5e351ba9c8ba20d947b89aa824ce1e0cd362322885f57662b0a96 ``` Mais à côté de ça, spontanément je n'ai pas trouvé d'exemple qui foirait sur la base de la longueur ``` php > echo(hash('sha256',"123456789012345678901234")."\n"); 05ae4505ae2b3f1bdc1f54a7e6b2669c3fcd3d89f4d0b55a25cbf2da29b9fcf1 js > hex_sha256('123456789012345678901234') "05ae4505ae2b3f1bdc1f54a7e6b2669c3fcd3d89f4d0b55a25cbf2da29b9fcf1" php > echo(hash('sha256',"1234567890123456789012345")."\n"); f2543ffdb4aff9265ad0337d3c26e5fec9ca78404e180a8a31ed9aed1520dcb6 js > hex_sha256('1234567890123456789012345') "f2543ffdb4aff9265ad0337d3c26e5fec9ca78404e180a8a31ed9aed1520dcb6" php > echo(hash('sha256',"12345678901234567890123456")."\n"); 5adcb5971681274f04187f2ebb0d69e09df67c8fc23ea13ee7b09c3d59ff5582 js > hex_sha256('12345678901234567890123456') "5adcb5971681274f04187f2ebb0d69e09df67c8fc23ea13ee7b09c3d59ff5582" php > echo(hash('sha256',"123456789012345678901234567")."\n"); bd671f60435a3b99d45bbb90abcbe4aa5336500bd060c986cce4229f7d46ff3a js > hex_sha256('123456789012345678901234567') "bd671f60435a3b99d45bbb90abcbe4aa5336500bd060c986cce4229f7d46ff3a" php > echo(hash('sha256',"123456789012345678901234567a")."\n"); 92efc698936bdc2751f07d1e96c7674b35d3a0bd55e4a9b56139714849b0e9ae js > hex_sha256('123456789012345678901234567a') "92efc698936bdc2751f07d1e96c7674b35d3a0bd55e4a9b56139714849b0e9ae" php > echo(hash('sha256',"123456789012345678901234567890")."\n"); f54e5c8f810648e7638d25eb7ed6d24b7e5999d588e88826f2aa837d2ee52ecd js > hex_sha256('123456789012345678901234567890') "f54e5c8f810648e7638d25eb7ed6d24b7e5999d588e88826f2aa837d2ee52ecd" php > echo(hash('sha256',"12345678901234567890123456789012")."\n"); e1b85b27d6bcb05846c18e6a48f118e89f0c0587140de9fb3359f8370d0dba08 js > hex_sha256('12345678901234567890123456789012') "e1b85b27d6bcb05846c18e6a48f118e89f0c0587140de9fb3359f8370d0dba08" php > echo(hash('sha256',"123456789012345678901234567890123")."\n"); 39bf8cc93fbdc84df4f7e3bb3f168b04089abb47631a16852aad5a1492c0248f js > hex_sha256('123456789012345678901234567890123') "39bf8cc93fbdc84df4f7e3bb3f168b04089abb47631a16852aad5a1492c0248f" php > echo(hash('sha256',"1234567890123456789012345678901234567890")."\n"); a4ebdd541454b84cc670c9f1f5508baf67ffd3fe59b883267808781f992a0b1d js > hex_sha256('1234567890123456789012345678901234567890') "a4ebdd541454b84cc670c9f1f5508baf67ffd3fe59b883267808781f992a0b1d" php > echo(hash('sha256',"1234567890123456789012345678901234567890az")."\n"); 4590c143ccf5db098251480a8c0fa7eb2db1b90e2b6e7f05cb84dbf752ee68a0 js > hex_sha256('1234567890123456789012345678901234567890az') "4590c143ccf5db098251480a8c0fa7eb2db1b90e2b6e7f05cb84dbf752ee68a0" php > echo(hash('sha256',"1234567890123456789012345678901234567890az.")."\n"); 5bc552af4b1563567c5505a582e5906e1e62d585054998246fd515bc2895cec6 js > hex_sha256('1234567890123456789012345678901234567890az.') "5bc552af4b1563567c5505a582e5906e1e62d585054998246fd515bc2895cec6" php > echo(hash('sha256',"1234567890123456789012345678901234567890az.01234567890")."\n"); 5ac86957fe2dc32d5ccd406a225f4be6b25b3ec0bbeec34b1d913de2977b3329 js > hex_sha256('1234567890123456789012345678901234567890az.01234567890') "5ac86957fe2dc32d5ccd406a225f4be6b25b3ec0bbeec34b1d913de2977b3329" php > echo(hash('sha256',"123456789012345678901234567890123456789012345678901234567890")."\n"); decc538c077786966ac863b5532c4027b8587ff40f6e3103379af62b44eae44d js > hex_sha256('123456789012345678901234567890123456789012345678901234567890') "decc538c077786966ac863b5532c4027b8587ff40f6e3103379af62b44eae44d" php > echo(hash('sha256',"1234567890123456789012345678901234567890123456789012345678901234567890")."\n"); 4d27a733bfffd740e782bdeb0e617de620e6836826b77445dbbdeda610292bdf js > hex_sha256('1234567890123456789012345678901234567890123456789012345678901234567890') "4d27a733bfffd740e782bdeb0e617de620e6836826b77445dbbdeda610292bdf" php > echo(hash('sha256',"123456789012345678901234.5678901234567890123456789012345678901234567890")."\n"); f92db7932a987c82968486e98cd3ef076b135d38f1100a5ea893fcae4e402732 js > hex_sha256('123456789012345678901234.5678901234567890123456789012345678901234567890') "f92db7932a987c82968486e98cd3ef076b135d38f1100a5ea893fcae4e402732" ```
Owner

Mais si je repars du hash fautif en enlevant un char à la fin à chaque fois il faut en enlever 4 pour arriver à un hash identique, et l'ajout d'un nouveau char refait foirer le hash, meme si il est différent de ce qu'on avait...

php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX")."\n");
f080242c98e5e351ba9c8ba20d947b89aa824ce1e0cd362322885f57662b0a96
js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX');
"47327e3fe3e25cb1967098d863a3044856d2f37b0fd0c04c656764b1bd172789"


php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlN")."\n");
c30b56ac6223098e5ab0264a4cea966d28b27a97ce140c57944befa2d8ca111f
js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlN');
"aba1b46155ee0aa3615cc9806b880bd120ed922aa8f3f28efcd091cd10f5a221"

php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68Ml")."\n");
078d6f8a9c51e183750892516410ccbf9c00c31612c517b56cb217e4f6adcb7f
js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68Ml');
"ed9bbffdcecd426e7e58685d38c179cc2a31515730ebd661fd6d9417f53a44ce"


php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68M")."\n");
6d42dbf25852b5b91d6d0310cb70a6f462fd096f18343bd90c322a38a142d6a8
js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68M');
"60b2562d391fbbf4070f420a3f2b5847c6208eb7e4f76935f165a52b7184bbe9"

php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68")."\n");
db41822aa7ef02218629871ea0419b0978881cd505120d07043ebc21964240f5
hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68');
"db41822aa7ef02218629871ea0419b0978881cd505120d07043ebc21964240f5"

php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68a")."\n");
83c7695e0e89760c1b98a85437f3f18728c7d638d29c52ce46cbee060090c38f
js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68a');
"563c36064a32a4f8f5a5c0db859a9a5088f633db62470e54ee2a5bcb7be446ec"

Mais si je repars du hash fautif en enlevant un char à la fin à chaque fois il faut en enlever 4 pour arriver à un hash identique, et l'ajout d'un nouveau char refait foirer le hash, meme si il est différent de ce qu'on avait... ``` php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX")."\n"); f080242c98e5e351ba9c8ba20d947b89aa824ce1e0cd362322885f57662b0a96 js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlNX'); "47327e3fe3e25cb1967098d863a3044856d2f37b0fd0c04c656764b1bd172789" php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlN")."\n"); c30b56ac6223098e5ab0264a4cea966d28b27a97ce140c57944befa2d8ca111f js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68MlN'); "aba1b46155ee0aa3615cc9806b880bd120ed922aa8f3f28efcd091cd10f5a221" php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68Ml")."\n"); 078d6f8a9c51e183750892516410ccbf9c00c31612c517b56cb217e4f6adcb7f js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68Ml'); "ed9bbffdcecd426e7e58685d38c179cc2a31515730ebd661fd6d9417f53a44ce" php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68M")."\n"); 6d42dbf25852b5b91d6d0310cb70a6f462fd096f18343bd90c322a38a142d6a8 js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68M'); "60b2562d391fbbf4070f420a3f2b5847c6208eb7e4f76935f165a52b7184bbe9" php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68")."\n"); db41822aa7ef02218629871ea0419b0978881cd505120d07043ebc21964240f5 hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68'); "db41822aa7ef02218629871ea0419b0978881cd505120d07043ebc21964240f5" php > echo(hash('sha256',"13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68a")."\n"); 83c7695e0e89760c1b98a85437f3f18728c7d638d29c52ce46cbee060090c38f js > hex_sha256('13864750866213ad61682b51.95536250yys0Z0u1Te8nZ0zCVMqK68a'); "563c36064a32a4f8f5a5c0db859a9a5088f633db62470e54ee2a5bcb7be446ec" ```
Owner

Et donc cf #2109 #3824 et #4927 pour décider comment on patch ça et sur quelles versions...

Et donc cf #2109 #3824 et #4927 pour décider comment on patch ça et sur quelles versions...
Owner

Donc, pour les versions < SPIP 4.1 qui sont en https, une solution est de définir la constante _AUTORISER_AUTH_FAIBLE dans config/mes_options à true.

À partir de SPIP 4.1, le système d’authentification est revu et transmets tout le temps le mot de passe en clair à SPIP (il est conseillé donc d’avoir un site en https donc), qui le hache en base de données selon l’état de l’art en vigueur actuellement.

Le mot de passe est hashé d’abord avec un une clé (poivre) spécifique au site, puis ce résultat hashé ou vérifié avec les fonctions PHP password_hash ou passsword_verify.

Un nouveau hash est enregistré en base à chaque identification réussie de l’auteur.

Les aleas d’auteur continuent de tourner également mais ne sont plus utilisés (comme sel) pour hacher le password. Le sel est effectivement géré par password_hash

Donc, pour les versions < SPIP 4.1 qui sont en https, une solution est de définir la constante `_AUTORISER_AUTH_FAIBLE` dans config/mes_options à `true`. À partir de SPIP 4.1, le système d’authentification est revu et transmets tout le temps le mot de passe en clair à SPIP (il est conseillé donc d’avoir un site en https donc), qui le hache en base de données selon l’état de l’art en vigueur actuellement. Le mot de passe est hashé d’abord avec un une clé (poivre) spécifique au site, puis ce résultat hashé ou vérifié avec les fonctions PHP `password_hash` ou `passsword_verify`. Un nouveau hash est enregistré en base à chaque identification réussie de l’auteur. Les aleas d’auteur continuent de tourner également mais ne sont plus utilisés (comme sel) pour hacher le password. Le sel est effectivement géré par `password_hash`
Owner

intégré par #5064

intégré par #5064
cerdic closed this issue 5 months ago
cerdic added this to the 4.1 milestone 5 months ago
Sign in to join this conversation.
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.