la sécurité du nouveau système d'authentification n'est pas bonne : l'ajout
du jajascript-md5 ouvre un trou.
if ($session_password_md5) $md5pass = $session_password_md5;
else $md5pass = md5($session_password);
.../...
$query = "SELECT * FROM spip_auteurs WHERE login='$login' AND pass='$md5pass'";
Si je tombe sur une copie de la base, je vois le pass-md5 d'un admin, je
l'envoie à spip_cookie sous le nom session_password_md5 avec le login, et je
suis logé.
Il faut faire un double md5 du mot de passe dans la base, un double md5 du
mot passé s'il est passé en clair, et un simple md5 s'il est passé en
md5-jaja. Ce qui impliquera une m-à-j de la base : faut pas rater notre
coup, sinon les accès seront tous morts ;).
J'y ai un peu réfléchi, et en fait on a deux alternatives :
1- se protéger contre le sniffage réseau en ajoutant un challenge,
mais ça oblige à ne pas se protéger contre le sniffage mysql
2- se protéger contre le sniffage mysql en ajoutant un niveau de
hash supplémentaire dans la base, mais ça oblige à ne pas se
protéger contre le sniffage réseau
La base est censée être protégée par la config du serveur, pour
le réseau on n'a aucune garantie (sauf HTTPS : très rare). Du
coup je pense plutôt pour le 1.
1- se protéger contre le sniffage réseau en ajoutant un challenge,
mais ça oblige à ne pas se protéger contre le sniffage mysql
2- se protéger contre le sniffage mysql en ajoutant un niveau de
hash supplémentaire dans la base, mais ça oblige à ne pas se
protéger contre le sniffage réseau
Pourquoi ? Il faut passer en notation, sinon on ne s'en sort pas :
C = mot en clair
md5(C) = mot de passe codé une fois, etc....
S = constante secret site
A = alea site
Base : actuellement stockage de md5(C) : je propose qu'on le convertisse, en
créant d'abord un secret pour le site, histoire d'entrer une variaton
supplémentaire dans la chaîne de calculs (paranoia?). Le nouveau
champ 'pass' contiendrait md5(S . md5(C)) [ou md5(md5(C)) si on
ne veut pas de secret].
* * *
Connexion normale : envoi de C, calcul de md5(S . md5(C)), comparaison avec
la base, seul risque = interception de C par sniffage réseau
Connexion jaja : envoi de md5(C), calcul de md5(S . md5(C)), comparaison
avec la base, seul risque = interception de md5(C) par sniffage
réseau (ne donne pas C, toutefois)
Base actuelle : md5(C) = si j le vois je peux l'envoyer depuis un "faux"
formulaire.
Base proposée : md5(S . md5(C)) --> si je le vois je ne peux rien en faire.
Base : actuellement stockage de md5(C) : je propose qu'on le convertisse, en
créant d'abord un secret pour le site, histoire d'entrer une variaton
supplémentaire dans la chaîne de calculs (paranoia?). Le nouveau
champ 'pass' contiendrait md5(S . md5(C)) [ou md5(md5(C)) si on
ne veut pas de secret].
Problème : si S est aussi dans la base, ça n'améliore rien.
Connexion normale : envoi de C, calcul de md5(S . md5(C)), comparaison avec
la base, seul risque = interception de C par sniffage réseau
Connexion jaja : envoi de md5(C), calcul de md5(S . md5(C)), comparaison
avec la base, seul risque = interception de md5(C) par sniffage
réseau (ne donne pas C, toutefois)
Donc tu vois bien qu'en essayant de protéger la base on se force à ne pas
se protéger contre le sniffage réseau ;))
Donc la question est : préfère-t-on une sécurité réseau ou une sécurité sur
la base ? Sachant que la base est *censée* être sécurisée (même sur un
hébergeur mutualisé) alors que le réseau ne l'est en général pas du tout,
je penche plutôt pour la sécurité réseau. Qu'en pensent les autres ?
* * *
Le challenge : un aléa est généré au moment de l'authentification, envoyé
dans le formulaire et stocké quelque part (ou, au choix, combiné avec l'alea
site pour former une paire non falsifiable). Puis le formulaire ajoute l'aléa
pour faire le second md5 => comme l'aléa change à chaque nouvelle auth, le
tout n'est rejouable que pendant la durée de vie de la session.
En clair, lors du login :
- créer alea A
- stocker dans spip_auteurs
- envoyer alea A au formulaire d'authentification
- le jajascript renvoie K = md5(A . md5(pass))
- le serveur prend K et le compare avec sa propre valeur
(A et md5(pass) récupérés depuis spip_auteurs)
Problème : si S est aussi dans la base, ça n'améliore rien.
Si, ça évite de comparer deux bases où toto aurait entré le même mot de
apsse. Pas grand chose, donc, mais pas "rien".
>Connexion normale : envoi de C, calcul de md5(S . md5(C)), comparaison
> avec la base, seul risque = interception de C par sniffage réseau
>
>Connexion jaja : envoi de md5(C), calcul de md5(S . md5(C)), comparaison
> avec la base, seul risque = interception de md5(C) par sniffage
> réseau (ne donne pas C, toutefois)
Donc tu vois bien qu'en essayant de protéger la base on se force à ne pas
se protéger contre le sniffage réseau ;))
Non, je ne vois pas ce que ça démontre : de toutes façons, à partir du
moment où tu te fais sniffer le mot de passe au moment où tu l'envoies, tu
es foutu (sauf challenge). Mais avec le double md5 tu ne peux plus utiliser
le champ 'pass' (vu sur un dump de la base) pour accéder au site.
Le challenge : un aléa est généré au moment de l'authentification, envoyé
dans le formulaire et stocké quelque part (ou, au choix, combiné avec l'alea
site pour former une paire non falsifiable). Puis le formulaire ajoute
l'aléa
pour faire le second md5 => comme l'aléa change à chaque nouvelle auth, le
tout n'est rejouable que pendant la durée de vie de la session.
En clair, lors du login :
- créer alea A
- stocker dans spip_auteurs
- envoyer alea A au formulaire d'authentification
- le jajascript renvoie K = md5(A . md5(pass))
- le serveur prend K et le compare avec sa propre valeur
(A et md5(pass) récupérés depuis spip_auteurs)
Oui, ça aussi évite le problème mentionné ci-dessus, et c'est pas
compatible. Il faut faire l'un ou l'autre, mais pas aucun des deux comme
actuellement. Sommes-nous d'accord ?