La journalisation des tentatives de connexion infructueuses expose les mots de passe

38

J'ai commencé à enregistrer les tentatives de connexion infructueuses sur mon site Web avec un message comme

Failed login attempt by qntmfred

J'ai remarqué que certaines de ces bûches ressemblaient à

Failed login attempt by qntmfredmypassword

Je suppose que certaines personnes ont échoué à la connexion parce qu'elles ont saisi leur nom d'utilisateur et leur mot de passe dans le champ du nom d'utilisateur. Les mots de passe sont hachés dans la base de données, mais si d'une manière ou d'une autre la base de données était compromise, ces messages de journalisation pourraient permettre à un attaquant de déterminer les mots de passe de n'importe quel petit pourcentage de personnes dont le nom de connexion avait échoué.

Y a-t-il une meilleure façon de gérer cela? Devrais-je même m'inquiéter de cette possibilité?

Kenwarner
la source
14
Oui, vous devriez vous en préoccuper.
FoolishSeth
4
Question intéressante car elle croise UX et la sécurité. Comme indiqué dans l'un des liens de Michael, vous pouvez éviter la plupart des cas en utilisant Javascript (côté client). Désactivez le bouton Connexion lorsque le champ du mot de passe est vide. Les utilisateurs sans Javascript peuvent toujours utiliser l'écran de connexion de cette façon, car le bouton ne sera pas désactivé dans ce cas.
MSalters

Réponses:

65

Essayez comme ça:

Si le nom d'utilisateur existe, enregistrez "tentative de connexion infructueuse username". Sinon, enregistrez 123.45.67.89plutôt " tentative de connexion infructueuse par IP ". Cela devrait résoudre le problème de la présence accidentelle de mots de passe dans le journal.

Maçon Wheeler
la source
14
Vous pouvez également rechercher un mot de passe vide et échouer avec une erreur appropriée dans ce cas.
Mike Weller
L'impression du nom d'utilisateur est le problème décrit par l'OP. Parfois, une connexion échouée est due au fait que l'utilisateur manque la touche [tab] et saisit rapidement le nom d'utilisateur et le mot de passe dans le champ du nom d'utilisateur et appuie sur Entrée. Votre suggestion ne gère pas cela.
BZink
7
@BZink: Oui c'est le cas. Si le nom d'utilisateur existe , enregistrez-le en tant que tel. Si l'utilisateur ajoute accidentellement le mot de passe au nom d'utilisateur, la chaîne résultante ne sera presque certainement pas également un nom d'utilisateur valide.
Mason Wheeler le
12

Pourquoi ne pas simplement vérifier si ce nom d'utilisateur existe dans la base de données? Cela vous laissera 2 résultats possibles.

  1. L'utilisateur a entré un nom d'utilisateur correct. Vous pouvez ensuite simplement enregistrer ce que vous enregistrez maintenant.

  2. L'utilisateur a entré son mot de passe dans le champ Nom d'utilisateur. Par conséquent, le nom d'utilisateur n'est pas valide. Entrez simplement une entrée de journal indiquant qu'il y a eu une tentative de connexion infructueuse par un utilisateur non identifié?

Et bien sûr, vous pouvez avoir un champ supplémentaire pour vous connecter ip, date et quoi non?

Galdikas
la source
3
Pourquoi ne pas ajouter un hachage du nom d'utilisateur à l'entrée du journal en # 2. Cela cachera le mot de passe, mais permettra en même temps à quelqu'un de consulter les journaux pour déterminer s'il y a plusieurs tentatives du même utilisateur non identifié.
emory
S'il n'y a pas d'enregistrement contenant le nom d'utilisateur, il est évident qu'ils se sont trompés. C'est donc toujours utile pour le dépannage.
JeffO
2
@emory, si un utilisateur a tapé par erreur son mot de passe avec son nom d'utilisateur, il n'existe aucun moyen viable d'extraire uniquement la partie nom d'utilisateur de la chaîne. Et quelqu'un qui saisit à plusieurs reprises son mot de passe pour le champ nom d'utilisateur est très peu probable, à mon avis. C'est une erreur "ponctuelle" que vous faites. Cela arrive aux meilleurs d'entre nous, mais je doute qu'il y ait quelqu'un qui soit assez stupide pour continuer à le faire sans s'en rendre compte: D
galdikas
@galdikas Il n'est pas nécessaire d'extraire quoi que ce soit du nom d'utilisateur. Par exemple, je suis utilisateur 'utilisateur' avec mot de passe 'mot de passe'. Je me connecte avec 'userpassword' et votre fonction de hachage mappe 'userpassword' à 17. Les journaux indiqueront «Échec de la tentative de connexion par un utilisateur non identifié 17».
Emory
1
@galdikas Il n'y a probablement personne assez stupide ou persistant pour continuer à le faire plusieurs fois, mais il existe des scripts assez stupides et persistants pour le faire des milliers de fois. Ne voudriez-vous pas connaître la différence?
Emory
1

Considérations:

  1. Pouvez-vous détecter le moment où cela s'est produit, par opposition à quelqu'un qui a mal saisi son nom d'utilisateur? Il peut être utile de noter les noms d’utilisateur mal typés, c’est-à-dire de répondre à la question "Pourquoi ne puis-je pas me connecter" avec la réponse "Vous avez mal saisi votre nom d’utilisateur, cela devrait être un tiret, pas un point" ou "Vous avez un point-virgule puis un espace - l’avez-vous coupé et collé ". Si vous avez un petit nombre d'utilisateurs payants de grande valeur (c'est-à-dire pas encore un autre réseau social), vous devrez probablement fournir ce type d'assistance.

  2. Quelle est l'action appropriée devrait quelqu'un faire cela? Les noms d'utilisateurs peuvent être des indicateurs de tentatives de piratage. Le fait que le nom d'utilisateur n'apparaisse pas dans votre liste ne signifie pas que vous n'avez pas besoin de savoir ce que c'était. Toutefois, si vous estimez qu'il s'agit d'un problème grave et que vous pouvez détecter le mot de passe correspondant, vous pouvez demander à l'utilisateur de changer de mot de passe après que cela se soit produit.

  3. Quelle est la pratique de l'industrie? La pratique de l’industrie consiste à consigner le champ Nom d’utilisateur, mais pas le champ Mot de passe. Vous êtes peu susceptible de se faire virer pour cela.

À moins que vous n'ayez des considérations inhabituelles, je suggérerais de suivre les pratiques de l'industrie et de consigner le champ nom d'utilisateur, peu importe. Considérez les modifications de mot de passe forcées comme suggestion 2 si vous pensez que cela est insuffisant.

Ben
la source
1

Juste pour être sûr, la connexion dans mon application actuelle ne stocke pas les paramètres transmis aux méthodes de connexion ou de réinitialisation du mot de passe. L'appel de journal a un paramètre facultatif qui contrôle cela, qui, lorsqu'il est défini sur true, remplace l'objet de paramètres stockés par [Redacted]. Bien sûr, je manque un peu de données, mais j'ai leurs adresses IP, et je préfère ne pas risquer d'obtenir quelque chose d'aussi sensible en texte clair.

Si vous voulez vraiment enregistrer ce genre de chose, je vous suggérerais, lors de la journalisation d'une tentative de connexion, de rechercher dans la base de données les utilisateurs dont le nom correspond à ce que vous avez dans le champ du nom d'utilisateur et de ne la stocker que si vous avez une correspondance. Sinon, vous ne stockez que comme "utilisateur inconnu". Vous pourriez avoir envie de vérifier si cette valeur contient ou non cette valeur, mais il y a toujours le risque d'obtenir des combinaisons comme [Utilisateur] [Mot de passe] et [UserPas] [épée], auquel cas vous pouvez vérifier par rapport à l'IP et en déduire que vous avez par inadvertance enregistré le début du mot de passe de quelqu'un en clair. Vous pouvez étendre cela au [utilisateur] [mot de passe] et au [mot de passe utilisateur] [??], ce qui est improbable mais possible. Dans ce cas, vous pouvez voir "connexion infructueuse par UserPassword" suivie de "connexion réussie par utilisateur" et en déduire tout.de mot de passe de l'utilisateur. En règle générale, pour être sûr, je dirais de ne pas enregistrer les noms d'utilisateurs à moins que la connexion soit réussie.

Modifier pour ajouter:

La plupart des arguments que les gens publient pour consigner le nom d'utilisateur des tentatives de connexion infructueuses sont, à mon avis, mieux gérés par d'autres méthodes.

Par exemple, il a été dit que lorsqu'un client demande "Pourquoi ne puis-je pas me connecter?", Les noms d'utilisateur enregistrés vous permettent de signaler des fautes de frappe. C’est vrai, mais le risque d’attraper des mots de passe ne vaut pas la peine. Pour ce faire, je redirigerais plutôt l'utilisateur vers le formulaire de connexion en cas d'échec, en mettant en surbrillance le champ du nom d'utilisateur et en le repeuplant avec ce qu'il aurait tapé pour qu'il puisse le voir par lui-même.

Un autre argument était que cela vous permettait d'identifier les tentatives de piratage; une chaîne d'échecs contre un nom d'utilisateur peut très bien être une tentative de forcer brutalement un mot de passe. Je le ferais en disposant une colonne "BadLogins" dans la table Utilisateurs, qui est incrémentée chaque fois qu'une connexion échoue avec un nom d'utilisateur correspondant à cet utilisateur et est réinitialisée à zéro si une connexion est réussie, après avoir indiqué à l'utilisateur "il y a eu x tentatives de connexion infructueuses depuis votre dernière connexion "et les aviser de la marche à suivre s’ils ne pensent pas que ces tentatives viennent d’eux. Si vous voulez être vraiment complet, vous pouvez avoir une autre colonne qui stocke la dernière valeur de la colonne BadLogins même après la connexion réussie, et / ou une colonne qui stocke la valeur la plus élevée de cette colonne, et / ou une colonne qui stocke le nombre total de connexions échouées de ce compte.

anaximandre
la source