Je travaille sur la fonctionnalité d'intégration de mon application Web et à un moment donné, je demande à un nouvel utilisateur de choisir un nom d'utilisateur.
Lorsque l'utilisateur arrive à ce point, j'ai son e-mail et un numéro de téléphone portable qui est validé avec un SMS et il/elle a passé le reCAPTCHA sans CAPTCHA de Google.
Je dois vérifier si le nom d'utilisateur que l'on choisit existe déjà et si c'est le cas, l'utilisateur est invité à en choisir un autre.
En parcourant le Web, je suis tombé sur certaines pages qui disent que la mise en œuvre d'une telle fonctionnalité fournit également aux attaquants un outil pour vérifier si un nom d'utilisateur existe.
Quelles sont les meilleures pratiques pour vérifier si un nom d'utilisateur existe?
Cette source dit qu'il est presque impossible d'éviter l'énumération des utilisateurs dans cette situation et retarder un attaquant est le mieux que vous puissiez faire:
Si vous êtes développeur, vous vous demandez peut-être comment protéger votre site contre ce type d'attaque. Eh bien, bien qu'il soit pratiquement impossible de rendre une installation d'inscription de compte à l'abri de l'énumération des noms d'utilisateurs, il est cependant possible d'éviter les attaques d'énumération des noms d'utilisateurs automatisées contre elle en implémentant un mécanisme CAPTCHA.
Cependant, j'ai peut-être manqué quelque chose - je suis également curieux de savoir si quelqu'un d'autre a une meilleure solution.
Vraiment ce qui se passe avec ce système
C'est mauvais. Vous devez donc empêcher plusieurs utilisateurs d'avoir le même nom d'utilisateur. Pour ce faire, vérifiez.
C'est le scénario qui vous est présenté et comment empêcher quelqu'un de l'utiliser de manière malveillante. À quel risque vous ouvrez-vous ici?
D'accord, cela offre un peu plus de sécurité et empêche toujours les utilisateurs d'avoir des e-mails et d'autres informations sensibles divulgués. Mais maintenant, vous voulez essayer d'atténuer les attaques. Comment tu fais ça?
Il existe ici quelques techniques pour l'empêcher, mais la meilleure est de loin la limitation du débit et les tentatives maximales que vous enregistrez par IP.
Lorsqu'un utilisateur essaie de s'enregistrer, il ne peut vérifier les noms d'utilisateur disponibles que si rapidement. En réalité, il faudra une ou deux secondes à une personne réelle pour saisir un nouveau nom d'utilisateur. Cela vous permet de faire quelques simples freins et contrepoids. Cependant, cela ne se produit vraiment que lorsqu'ils essaient de s'inscrire. Lorsqu'un utilisateur vous attaque et utilise un nom d'utilisateur qui n'est pas enregistré, tout ce qui se passe, c'est qu'il a enregistré ce nom d'utilisateur. Tant pis. Maintenant, ils doivent recommencer le processus d'inscription, et voici où vous pouvez vérifier.
Maintenant, cet attaquant s'est exposé et a été banni au niveau IP. Vous savez qu'il se passe quelque chose de mal ici, avez un journal des noms d'utilisateurs qui pourraient avoir été lus, et mieux encore, il n'y a pas eu de fuite d'informations personnelles. Bon travail!
Cependant, vous devez maintenant revenir en arrière et annuler l'enregistrement de tous les comptes créés pour tenter de trouver d'autres comptes. Heureusement que vous avez ces journaux!
Voici un gros défaut dont vous devez être conscient lorsque vous ne liez pas un compte à un e-mail: Le nom d'utilisateur peut être préenregistré et conservé contre rançon . Il est alors extrêmement difficile de prouver la propriété du nom d'utilisateur. Cela permet à quelqu'un de faire un autre type d'attaque contre votre système où il essaie simplement de pré-enregistrer un grand nombre de comptes de personnes et de les tenir en rançon. J'espère que vous avez un journal des vérifications ci-dessus afin que vous puissiez essayer de les attraper dans l'acte.
Vous avez mentionné qu'ils avaient déjà suivi le processus de confirmation par e-mail, donc une autre façon de le gérer à ce stade est de le lier à l'e-mail à la place. Après l'inscription, s'ils veulent changer leur email, ils devront se connecter et envoyer une demande avec un lien vers leur email pour le changer. Cela peut être fait avec un jeton sensible au temps. Maintenant, ils peuvent aussi avoir un nom d'utilisateur à afficher sur le site. Les pièges sont également atténués ici car le nom d'affichage peut se chevaucher et il n'y a aucun moyen d'essayer d'accéder à un autre compte avec ces informations, mais l'e-mail fournit une vérification de la vérité (et éventuellement une sorte d'identifiant physique comme une image de profil)
Lorsqu'un utilisateur essaie de se connecter, il saisit son nom d'utilisateur. Lors de l'inscription, on vous dit si un nom d'utilisateur est pris ou non. Si vous trouvez un nom d'utilisateur pris, vous pouvez essayer de vous connecter avec lui et éventuellement le pirater.
Solution qui est aussi un autre problème:
S'ils devaient se connecter avec un e-mail, la connaissance de la saisie d'un nom d'utilisateur n'aidera pas - vous vous connectez avec un e-mail et non un nom d'utilisateur, vous ne pouvez donc pas savoir quoi saisir dans le formulaire de texte de l'e-mail lorsque vous savez qu'il existe le nom d'utilisateur helloman
. Mais maintenant, le problème est de dire à l'utilisateur si l'e-mail est pris.
Solution - lors de l'inscription, ne leur dites pas si l'e-mail est pris mais dites-leur qu'un e-mail de confirmation a été envoyé. Envoyez-leur un e-mail, si l'e-mail a été enregistré avant d'envoyer un e-mail disant que quelqu'un a essayé d'enregistrer son e-mail. Si celui qui a tenté de s'inscrire [email protected]
n'est pas le véritable helloman qu'il ne verra probablement pas la boîte de réception de helloman. Et si le véritable helloman a essayé de créer un nouveau compte avec son e-mail déjà enregistré, alors seulement il recevra un e-mail lui disant qu'il s'est déjà enregistré. À moins qu'il n'y ait un pirate qui a réussi à pirater helloman, mais beaucoup de gens comme helloman ne sont pas stupides et n'utilisent pas password
comme mot de passe, les systèmes de messagerie les plus courants sont également très sécurisés de nos jours, donc ce n'est pas à craindre ( et s'il les a piratés, ce n'est pas notre problème (si vous configurez votre propre serveur de messagerie pour vous et votre personnel)).
Permettre à un utilisateur (ou un attaquant) de savoir si des noms d'utilisateur existent ou non est connu sous le nom de vulnérabilité "énumération des noms d'utilisateurs". Cela se résume bien ici :
En tant qu'attaquant, si je peux utiliser votre page de connexion ou de mot de passe oublié pour réduire ma liste de 10000 cibles à 1000 cibles, je le ferai.
Vous pouvez ajouter une "page d'inscription" à cette liste. Cela aide un attaquant dans toute campagne de phishing ou toute attaque par devinette de mot de passe. C'est également un problème de confidentialité si la femme de Bob, Alice, peut savoir si [email protected] existe sur Ashley Madison.com.
Fondamentalement, si vous autorisez les utilisateurs à choisir leur propre nom d'utilisateur qui est distinct de leur adresse e-mail, pour vous prémunir contre l'énumération des utilisateurs, vous devez autoriser la connexion avec e-mail/mot de passe uniquement, et simplement utiliser le nom d'utilisateur comme moyen d'identification avec les autres utilisateurs du site.
De cette façon, il n'y a aucune vulnérabilité en disant Désolé, le nom d'utilisateur foobar est pris, veuillez en sélectionner un autre .
En effet, contrairement à l'adresse e-mail, ces noms d'utilisateur ne seront pas uniques au monde dans le monde. Par conséquent, aucune confidentialité de l'utilisateur n'est violée lorsque vous dites qu'une est prise. De plus, comme vous ne pouvez pas vous connecter directement à l'aide du nom d'utilisateur, cela ne donnerait pas lieu à une vulnérabilité d'énumération des utilisateurs.
En prime, cela rend également la récupération de compte et l'inscription un processus plus simple (ce qui est toujours bon pour la sécurité). Autrement dit, il n'y a pas besoin de la fonctionnalité "nom d'utilisateur oublié" ainsi que "mot de passe oublié" - comme ils se connectent avec leur adresse e-mail, dont ils se souviendront, c'est la seule chose dont ils ont besoin pour retrouver l'accès en supposant qu'ils ont toujours accès à leur compte email. Assurez-vous cependant d'empêcher l'énumération des utilisateurs sur vos adresses e-mail - voir cette réponse .
En guise de mise à jour de cette réponse, je remarque que vous dites que vous ne souhaitez pas utiliser l'e-mail comme nom d'utilisateur au cas où l'utilisateur déciderait de changer son adresse e-mail. La seule raison pour laquelle je peux voir cela comme un problème si dans votre architecture vous utilisez "nom d'utilisateur" comme clé primaire, donc toute mise à jour de l'adresse e-mail (s'il s'agissait d'un nom d'utilisateur) entraînerait la nécessité pour chaque table liée de être mis à jour. La réarchitecture de ceci pour utiliser des PK indépendants serait la solution préférée à cela plutôt que de rendre le nom d'utilisateur statique. (A noté une grande hypothèse ici de ma part sur vos raisons.)
Il y a de bonnes réponses de @SilverlightFox et @MaxTheBackspace.
Je veux juste clarifier une chose: il devrait pas être par défaut possible à tout moment dans l'application pour permettre aux utilisateurs d'énumérer un identifiant unique global (probable) comme une adresse e-mail. Pas même une fois. Pas avec la surveillance d'adresse IP et la limitation de débit et un CAPTCHA en langage Klingon créé avec la peinture au doigt par un tout-petit.
Il ne s'agit pas seulement de la sécurité de votre service mais de la confidentialité de l'utilisateur.
Ce n'est généralement pas un problème sérieux à moins que vos noms d'utilisateur soient une adresse e-mail, ce qui autoriserait le spam ou phishing de vos utilisateurs. (Ou aussi potentiellement si vous fournissez une API de messagerie.)
Cela dit , si vous pensez que le nom d'utilisateur sous-jacent doit être un secret: laissez les nouveaux utilisateurs choisir un nom d'affichage, mais ne leur permettez pas de choisir leur nom d'utilisateur sous-jacent . Au lieu de cela, offrez OAuth ou ajoutez un nombre aléatoire ou Word à leur nom d'affichage à utiliser lors de la connexion.
Et même dans ce cas, si vous disposez d'une API de messagerie, la mesure de protection la plus claire consiste à s'assurer que les messages sont clairement marqués avec le nom d'utilisateur d'origine.
Il peut être préférable que le processus de connexion fonctionne avec un e-mail et non avec un nom d'utilisateur. Si vous avez besoin d'un nom d'utilisateur en n'en faisant pas un élément d'authentification, un attaquant ne peut plus utiliser la vérification de la disponibilité du nom d'utilisateur comme outil malveillant. À ce stade, le nom d'utilisateur n'est qu'une vanité et une identité publique.
Je sais dans un commentaire vous avez déclaré que vous vouliez que votre utilisateur puisse modifier son adresse e-mail, donc vous ne vouliez pas l'utiliser pour vous connecter. C'est une pratique tout à fait acceptable de le faire et d'autoriser le changement d'adresse e-mail. Le site même sur lequel vous vous trouvez procède de la même manière.
Alors maintenant, vous avez la question de vérifier si quelqu'un s'est déjà inscrit avec une adresse e-mail. Pour commencer, il est beaucoup plus difficile pour quelqu'un de deviner [email protected]
sur someguy
. Et puis, si l'attaquant connaissait someguy
sur votre service et voulait l'attaquer spécifiquement, il devrait connaître l'e-mail avec lequel il s'est inscrit ainsi que son mot de passe par opposition à un simple mot de passe.
Mais des attaques automatisées et des attaques manuelles persistantes se produisent. Il est très difficile de dire si quelqu'un a essayé 50 combinaisons de noms d'utilisateur à la recherche d'informations ou s'il essaie simplement de trouver le nom d'utilisateur parfait qu'il veut légitimement utiliser. Mais si quelqu'un essaie de s'inscrire en utilisant 5 e-mails différents, c'est un drapeau rouge beaucoup plus grand pour les abus.
Ainsi, en passant l'authentification par e-mail via le nom d'utilisateur, vous obtenez:
La chute est une fuite potentielle de la vie privée comme mentionné par Lukas dans les commentaires . Si quelqu'un voulait savoir si un certain utilisateur était membre et qu'il savait avec quel email il s'inscrirait, il pourrait le recouper avec votre système d'inscription.
Du point de vue de l'interface utilisateur/convivialité, si j'ai déjà pris 3 mesures (e-mail, téléphone/recaptcha), cela réduit la probabilité d'une attaque de machine, et tout autre obstacle réduira le nombre de personnes qui souhaitent s'inscrire mais abandonner dans la frustration. Personnellement, cela ne me dérange pas du tout si j'essaie de choisir MarkyMark
(Non, je ne suis pas le rappeur), et si un autre rappeur en herbe a utilisé ce nom, je préfère de loin le le site Web me dit que MarkyMark est déjà utilisé (et comme d'autres l'ont suggéré, offre également la possibilité de leur permettre de se connecter en tant que MarkyMark
au cas où j'oublierais que je m'étais déjà enregistré il y a 3 ans), et si le site me propose d'essayer MarkyMark345
ou MarkyMarkyMark
- cela ne veut pas nécessairement dire qu'il y a MarkyMark1
à MarkyMark344
déjà utilisé. J'apprécie les suggestions. En fait, une fois qu'un site a suggéré MarkyMark78
et j'ai essayé MarkyMark77
et était réussi.
L'énumération des noms d'utilisateur est une menace car la combinaison nom d'utilisateur + mot de passe donnera à un attaquant un accès au compte/système.
Combien d'une menace qui dépend de votre système. Par exemple, dans un forum où le nom d'utilisateur est de toute façon attaché à chaque message, cette menace est très faible. Si vous appliquez des mots de passe forts, cela réduit la menace.
Dans votre scénario, en raison de toutes les données que vous avez vérifiées avant d'arriver à cette étape, l'énumération serait incroyablement coûteuse, alors arrêtez de vous foutre le cerveau et allez-y et dites-lui "nom d'utilisateur pris", avec des alternatives proposées comme suggéré par Mark Stewart.