Notre application a récemment subi des tests de pénétration. Le test a trouvé une critique faille de sécurité, qui est essentiellement:
Le rapport recommande de chiffrer ou de hacher le mot de passe côté client (en utilisant JavaScript), d'une manière qui ne peut pas être relue (par exemple en utilisant un tampon/horodatage unique). Ils ne pouvaient pas recommander un schéma spécifique (ils mentionnaient des certificats clients, ce qui pouvait ne pas être pratique pour une grande application).
Est-il utile de crypter ou de hacher le mot de passe avant de le publier? C'est une pratique courante?
Cette recommandation n'a aucun sens: le code JavaScript utilisé pour hacher ou crypter le mot de passe doit également être transféré au client. Si l'attaquant est capable de monter une attaque de l'homme du milieu, il pourra également inspecter le code JavaScript utilisé pour le chiffrement ou pourrait même le remplacer par quelque chose d'autre (comme pas de chiffrement).
Le hachage au lieu du chiffrement a encore moins de sens, car cela ne fonctionnerait que si le serveur acceptait le mot de passe haché au lieu du vrai mot de passe. Dans ce cas, l'attaquant n'aurait même pas besoin de connaître le mot de passe, il a seulement besoin de connaître le hachage.
Les certificats client pourraient être utiles car vous ne pouvez pas monter une attaque SSL man-in-the-middle qui préserve le certificat client (et une rétrogradation vers HTTP simple n'enverrait pas non plus le certificat). Mais, comme vous devez d'abord distribuer les certificats aux clients et les faire installer dans le navigateur, cette solution ne fonctionne que lorsque vous avez peu de clients.
En dehors de cela: si l'attaquant est au milieu, il n'a peut-être pas du tout besoin du mot de passe. Tout ce dont il a besoin, c'est que la victime se soit connectée et que l'attaquant puisse reprendre la session existante.
Il peut également être utile de détecter une telle situation d'homme au milieu, afin de pouvoir informer l'utilisateur et refuser la connexion à partir de réseaux compromis. Quelques idées pour détecter les rétrogradations de connexion (c'est-à-dire http à l'attaquant qui le transmet en https):
Et sur la façon de détecter l'homme du milieu avec de faux certificats:
Bien sûr, tout cela n'aide que contre un attaquant qui n'est pas vraiment déterminé à pirater en particulier vous, mais prend simplement les cibles les plus faciles. Dans ce cas, tout ce que vous devez faire est d'être un peu plus difficile à attaquer que les autres.
Je suggérerais d'implémenter HTTP Strict Transport Security à la place, ce qui empêche l'utilisateur d'accepter le certificat usurpé en premier lieu.
Si vous voulez ignorer que l'attaquant pourrait facilement remplacer le code Javascript lors d'une attaque MITM active:
Vous pouvez générer une clé de chiffrement asymétrique, fournir au client cette clé publique pour l'utiliser pour chiffrer le côté client du mot de passe. Si vous utilisez une nouvelle clé pour chaque connexion, personne ne devrait pouvoir rejouer le mot de passe.