Le guide définitif de l'authentification des sites Web par formulaire

Authentification par formulaire pour les sites web

Nous pensons que Stack Overflow ne devrait pas seulement être une ressource pour des questions techniques très spécifiques, mais aussi pour des directives générales sur la façon de résoudre des variations de problèmes communs. "Form based authentication for websites&quot ; devrait être un bon sujet pour une telle expérience.

Il devrait inclure des sujets tels que :

  • Comment se connecter
  • Comment se déconnecter
  • Comment rester connecté
  • Gestion des cookies (y compris les paramètres recommandés)
  • Cryptage SSL/HTTPS
  • Comment stocker les mots de passe
  • Utilisation de questions secrètes
  • Fonctionnalité de nom d'utilisateur/mot de passe oublié
  • Utilisation de nonces pour empêcher les cross-site request forgeries (CSRF)
  • [OpenID][2]
  • Case à cocher "Se souvenir de moi" (Remember me&quot)
  • Autocomplétion des noms d'utilisateur et des mots de passe par le navigateur
  • URLs secrètes (publiques [URL][4] protégées par digest)
  • Vérification de la force du mot de passe
  • Validation des e-mails
  • Et bien plus encore sur [l'authentification basée sur un formulaire][3]...

Il ne devrait pas inclure des choses comme :

  • Rôles et autorisations
  • L'authentification de base HTTP

Veuillez nous aider :

  1. Suggérant des sous-thèmes
  2. Soumettant de bons articles sur ce sujet
  3. Editer la réponse officielle

[1] : http://en.wikipedia.org/wiki/OpenID [2] : http://openid.net/ [3] : http://en.wikipedia.org/wiki/Form-based_authentication [4] : https://en.wikipedia.org/wiki/Uniform_Resource_Locator

Solution

Première partie : Comment se connecter ?

Nous supposons que vous savez déjà comment construire un formulaire HTML de connexion et de mot de passe qui envoie les valeurs à un script côté serveur pour l'authentification. Les sections suivantes traitent des modèles d'authentification pratiques et de la manière d'éviter les pièges de sécurité les plus courants. Pour HTTPS ou pas pour HTTPS? À moins que la connexion ne soit déjà sécurisée (c'est-à-dire qu'elle passe par un tunnel HTTPS utilisant SSL/TLS), les valeurs de votre formulaire de connexion seront envoyées en clair, ce qui permet à toute personne écoutant la ligne entre le navigateur et le serveur Web de lire les connexions au moment où elles passent. Ce type d'écoute est pratiqué couramment par les gouvernements, mais en général, nous n'aborderons pas les fils "possédés", si ce n'est pour dire ceci : Utilisez simplement HTTPS. En substance, le seul moyen pratique de se protéger contre l'écoute électronique et le reniflement de paquets pendant la connexion est d'utiliser HTTPS ou un autre système de cryptage basé sur un certificat (par exemple, [TLS][1]) ou un système éprouvé de réponse à un défi (par exemple, le SRP basé sur [Diffie-Hellman][2]). Toute autre méthode peut être facilement contournée par un attaquant qui écoute aux portes. Bien sûr, si vous êtes prêt à être un peu moins pratique, vous pouvez également utiliser une forme d'authentification à deux facteurs (par exemple, l'application Google Authenticator, un livre de codes physique de type "guerre froide" ou un générateur de clés RSA). S'il est appliqué correctement, cela pourrait fonctionner même avec une connexion non sécurisée, mais il est difficile d'imaginer qu'un développeur soit prêt à mettre en œuvre une authentification à deux facteurs mais pas SSL. (Ne pas) Roll-your-own JavaScript encryption/hashing Compte tenu du coût et de la difficulté technique de la mise en place d'un certificat SSL sur votre site Web, certains développeurs sont tentés de mettre en place leurs propres schémas de hachage ou de cryptage dans le navigateur afin d'éviter de transmettre des identifiants en clair sur un fil non sécurisé. Bien que cette idée soit noble, elle est essentiellement inutile (et peut constituer une [faille de sécurité][3]) si elle n'est pas associée à l'une des solutions ci-dessus, à savoir la sécurisation de la ligne par un chiffrement fort ou l'utilisation d'un mécanisme éprouvé de réponse à un défi (si vous ne savez pas ce que c'est, sachez qu'il s'agit de l'un des concepts les plus difficiles à prouver, à concevoir et à mettre en œuvre en matière de sécurité numérique). S'il est vrai que le hachage du mot de passe peut être efficace contre la divulgation du mot de passe, il est vulnérable aux attaques par rejeu, aux attaques Man-In-The-Middle / aux détournements (si un attaquant peut injecter quelques octets dans votre page HTML non sécurisée avant qu'elle n'atteigne votre navigateur, il peut simplement commenter le hachage dans le JavaScript), ou aux attaques par force brute (puisque vous remettez à l'attaquant à la fois le nom d'utilisateur, le sel et le mot de passe haché). CAPTCHAS contre l'humanité Le [CAPTCHA][4] est destiné à contrecarrer une catégorie spécifique d'attaques : les essais et erreurs automatisés par dictionnaire/force brute sans opérateur humain. Il ne fait aucun doute qu'il s'agit d'une menace réelle, mais il existe des moyens d'y faire face de manière transparente sans avoir recours à un CAPTCHA, notamment des systèmes de limitation de la connexion côté serveur correctement conçus - nous en parlerons plus tard. Sachez que les implémentations CAPTCHA ne sont pas toutes créées de la même manière ; elles ne sont souvent pas résolubles par l'homme, la plupart d'entre elles sont en fait inefficaces contre les bots, toutes sont inefficaces contre la main-d'œuvre bon marché du tiers-monde (selon [OWASP][5], le taux actuel dans les ateliers clandestins est de 12 $ pour 500 tests), et certaines implémentations peuvent être techniquement illégales dans certains pays (voir [OWASP Authentication Cheat Sheet][6]). Si vous devez utiliser un CAPTCHA, utilisez le [reCAPTCHA][7] de Google, car il est difficile à lire par OCR par définition (puisqu'il utilise des scans de livres déjà mal classés par OCR) et fait tout son possible pour être convivial. Personnellement, j'ai tendance à trouver les CAPTCHAS ennuyeux, et je ne les utilise qu'en dernier recours lorsqu'un utilisateur n'a pas réussi à se connecter un certain nombre de fois et que les délais d'étranglement sont au maximum. Cela se produira assez rarement pour être acceptable, et cela renforce le système dans son ensemble. Stockage des mots de passe et vérification des connexions Après tous les piratages et les fuites de données des utilisateurs qui ont fait l'objet d'une grande publicité ces dernières années, tout le monde le sait peut-être, mais il faut le dire : Ne stockez pas les mots de passe en clair dans votre base de données. Les bases de données des utilisateurs sont régulièrement piratées, divulguées ou glanées par injection SQL, et si vous stockez des mots de passe bruts, en clair, la sécurité de votre connexion est immédiatement compromise. Si vous ne pouvez pas stocker le mot de passe, comment vérifier que la combinaison identifiant/mot de passe POSTée par le formulaire de connexion est correcte ? La réponse est un hachage utilisant une [fonction de dérivation de clé][24]. Chaque fois qu'un nouvel utilisateur est créé ou qu'un mot de passe est modifié, vous prenez le mot de passe et le faites passer par une fonction de dérivation de clé (KDF), comme Argon2, bcrypt, scrypt ou PBKDF2, transformant le mot de passe en clair ("correcthorsebatterystaple") en une longue chaîne à l'aspect aléatoire, qui est beaucoup plus sûre à stocker dans votre base de données. Pour vérifier une connexion, vous exécutez la même fonction de hachage sur le mot de passe saisi, en ajoutant cette fois le sel et en comparant la chaîne de hachage résultante à la valeur stockée dans votre base de données. Argon2, bcrypt et scrypt stockent déjà le sel avec le hachage. Consultez cet [article][23] sur sec.stackexchange pour des informations plus détaillées. La raison pour laquelle un sel est utilisé est que le hachage en lui-même n'est pas suffisant - vous voudrez ajouter un "sel" pour protéger le hachage contre les [rainbow tables][8]. Un sel empêche effectivement deux mots de passe qui correspondent exactement d'être stockés sous la même valeur de hachage, empêchant ainsi l'ensemble de la base de données d'être analysée en une seule fois si un attaquant exécute une attaque par devinette de mot de passe. Un hachage cryptographique ne devrait pas être utilisé pour le stockage des mots de passe car les mots de passe choisis par l'utilisateur ne sont pas assez forts (c'est-à-dire qu'ils ne contiennent généralement pas assez d'entropie) et une attaque par devinette de mot de passe pourrait être réalisée en un temps relativement court par un attaquant ayant accès aux hachages. C'est la raison pour laquelle les KDF sont utilisés - ils permettent effectivement ["d'étirer la clé"][25], ce qui signifie que chaque mot de passe deviné par un attaquant entraîne de multiples répétitions de l'algorithme de hachage, par exemple 10 000 fois, ce qui fait que l'attaquant devine le mot de passe 10 000 fois plus lentement. Données de session - "Vous êtes connecté en tant que Spiderman69"**. Une fois que le serveur a vérifié l'identifiant et le mot de passe dans votre base de données d'utilisateurs et qu'il a trouvé une correspondance, le système doit pouvoir se souvenir que le navigateur a été authentifié. Ce fait ne doit être stocké que dans les données de session, côté serveur.

Si vous n'êtes pas familier avec les données de session, voici comment elles fonctionnent : Une chaîne unique générée de manière aléatoire est stockée dans un cookie qui expire et utilisée pour référencer une collection de données - les données de session - qui est stockée sur le serveur. Si vous utilisez un framework MVC, cette opération est sans doute déjà gérée. Dans la mesure du possible, assurez-vous que le cookie de session a les drapeaux secure et HTTP Only activés lorsqu'il est envoyé au navigateur. L'indicateur HttpOnly offre une certaine protection contre la lecture du cookie par une attaque XSS. Le drapeau "secure" garantit que le cookie est renvoyé uniquement via HTTPS, ce qui le protège contre les attaques par reniflage du réseau. La valeur du cookie ne doit pas être prévisible. Lorsqu'un cookie faisant référence à une session inexistante est présenté, sa valeur doit être remplacée immédiatement pour éviter la [fixation de session][9].

PARTIE II : Comment rester connecté - La fameuse case à cocher "Se souvenir de moi"

Les cookies de connexion persistants (fonctionnalité "Se souvenir de moi") constituent une zone dangereuse ; d'une part, ils sont tout aussi sûrs que les connexions classiques lorsque les utilisateurs comprennent comment les manipuler ; d'autre part, ils représentent un risque de sécurité énorme entre les mains d'utilisateurs négligents, qui peuvent les utiliser sur des ordinateurs publics et oublier de se déconnecter, et qui peuvent ne pas savoir ce que sont les cookies de navigateur ou comment les supprimer. Personnellement, j'aime les connexions persistantes pour les sites Web que je visite régulièrement, mais je sais comment les utiliser en toute sécurité. Si vous êtes certain que vos utilisateurs en savent autant, vous pouvez utiliser les identifiants permanents en toute bonne conscience. Si ce n'est pas le cas, vous pouvez souscrire à la philosophie selon laquelle les utilisateurs qui sont négligents avec leurs identifiants de connexion s'exposent eux-mêmes à un piratage. Ce n'est pas comme si nous allions chez nos utilisateurs pour leur arracher tous les Post-It avec les mots de passe qu'ils ont alignés sur le bord de leur écran. Bien sûr, certains systèmes ne peuvent pas se permettre d'avoir n'importe quel compte piraté ; pour ces systèmes, il n'y a aucun moyen de justifier des logins persistants. **Si vous décidez d'implémenter des cookies de connexion persistants, voici comment vous devez vous y prendre

  1. Tout d'abord, prenez le temps de lire [l'article de Paragon Initiative][10] sur le sujet. Vous devrez prendre en compte un certain nombre d'éléments, que l'article explique très bien.
  2. Et pour répéter l'un des pièges les plus courants, NE STOCKEZ PAS LE COOKIE DE LOGIN PERSISTANT (TOKEN) DANS VOTRE BASE DE DONNEES, SEULEMENT UN HASH DE CELUI-CI Le jeton de connexion est équivalent au mot de passe, donc si un attaquant mettait la main sur votre base de données, il pourrait utiliser les jetons pour se connecter à n'importe quel compte, comme s'il s'agissait de combinaisons login-mot de passe en clair. Par conséquent, utilisez le hachage (selon https://security.stackexchange.com/a/63438/5002, un hachage faible fera l'affaire à cette fin) pour stocker les jetons de connexion persistants.

    PARTIE III : Utilisation des questions secrètes

    Ne mettez pas en œuvre les "questions secrètes ". La fonction "questions secrètes" est un anti-modèle de sécurité. Lisez l'article du lien numéro 4 de la liste MUST-READ. Vous pouvez demander à Sarah Palin ce qu'elle en pense, après que son compte de messagerie Yahoo ! ait été piraté lors d'une précédente campagne présidentielle parce que la réponse à sa question de sécurité était... "Wasilla High School" ! Même avec des questions spécifiées par l'utilisateur, il est fort probable que la plupart des utilisateurs choisissent l'une ou l'autre :

  • Une question secrète "standard" comme le nom de jeune fille de la mère ou l'animal de compagnie préféré.
  • Une question simple que n'importe qui pourrait extraire de son blog, de son profil LinkedIn, etc.
  • Toute question à laquelle il est plus facile de répondre que de deviner son mot de passe. Ce qui, pour tout mot de passe décent, est toutes les questions que vous pouvez imaginer. **En conclusion, les questions de sécurité sont intrinsèquement peu sûres sous pratiquement toutes leurs formes et variations, et ne devraient pas être employées dans un schéma d'authentification pour quelque raison que ce soit. La véritable raison pour laquelle les questions de sécurité existent dans la nature est qu'elles permettent d'économiser le coût de quelques appels au support technique de la part d'utilisateurs qui ne peuvent pas accéder à leur courrier électronique pour obtenir un code de réactivation. Et ce, au détriment de la sécurité et de la réputation de Sarah Palin. Cela en vaut-il la peine ? Probablement pas.

    PARTIE IV : Fonctionnalité de mot de passe oublié

    J'ai déjà mentionné pourquoi vous ne devriez jamais utiliser de questions de sécurité pour gérer les mots de passe oubliés/perdus des utilisateurs ; il va également sans dire que vous ne devriez jamais envoyer par e-mail aux utilisateurs leurs mots de passe réels. Il existe au moins deux autres pièges trop courants à éviter dans ce domaine :

  1. Ne pas réinitialiser un mot de passe oublié en un mot de passe fort généré automatiquement - ces mots de passe sont notoirement difficiles à retenir, ce qui signifie que l'utilisateur doit soit le changer, soit le noter - par exemple, sur un Post-It jaune vif sur le bord de son écran. Au lieu de définir un nouveau mot de passe, laissez les utilisateurs en choisir un immédiatement - ce qu'ils veulent faire de toute façon. (Une exception à cette règle peut être faite si les utilisateurs utilisent tous un gestionnaire de mots de passe pour stocker/gérer des mots de passe qu'il serait normalement impossible de retenir sans les écrire).
  2. Toujours hacher le code/token du mot de passe perdu dans la base de données. AGAIN, ce code est un autre exemple d'équivalent de mot de passe, il DOIT donc être haché au cas où un attaquant mettrait la main sur votre base de données. Lorsqu'un code de mot de passe perdu est demandé, envoyez le code en clair à l'adresse électronique de l'utilisateur, puis hachurez-le, enregistrez le hachage dans votre base de données - et jetez l'original. Tout comme un mot de passe ou un jeton de connexion persistant. Une dernière remarque : assurez-vous toujours que votre interface pour la saisie du "code de mot de passe perdu" est au moins aussi sécurisée que votre formulaire de connexion lui-même, ou un attaquant l'utilisera simplement pour obtenir l'accès. S'assurer que vous générez des "codes de mot de passe perdu" très longs (par exemple, 16 caractères alphanumériques sensibles à la casse) est un bon début, mais envisagez d'ajouter le même schéma d'étranglement que vous faites pour le formulaire de connexion lui-même.

    Partie V : Vérification de la force du mot de passe

    Tout d'abord, vous voudrez lire ce petit article pour vérifier la réalité : [Les 500 mots de passe les plus courants] [11] D'accord, cette liste n'est peut-être pas la liste canonique des mots de passe les plus courants sur tous les systèmes, où que ce soit, mais elle donne une bonne idée de la médiocrité avec laquelle les gens choisissent leurs mots de passe lorsqu'aucune politique n'est appliquée. De plus, la liste semble effroyablement proche de la maison lorsque vous la comparez aux analyses publiques des mots de passe récemment volés. Ainsi : En l'absence d'exigences minimales en matière de force des mots de passe, 2 % des utilisateurs utilisent l'un des 20 mots de passe les plus courants. Autrement dit, si un attaquant n'a droit qu'à 20 tentatives, 1 compte sur 50 sur votre site Web sera craquable. Pour contrer ce phénomène, il faut calculer l'entropie d'un mot de passe, puis appliquer un seuil. Le National Institute of Standards and Technology (NIST) [Special Publication 800-63][12] propose un ensemble de très bonnes suggestions. Ces suggestions, combinées à une analyse du dictionnaire et de la disposition du clavier (par exemple, "qwertyuiop" est un mauvais mot de passe), peuvent [rejeter 99 % de tous les mots de passe mal choisis][13] à un niveau de 18 bits d'entropie. Le simple fait de calculer la force d'un mot de passe et de [montrer un indicateur visuel de la force][14] à un utilisateur est une bonne chose, mais insuffisante. Si cette mesure n'est pas appliquée, de nombreux utilisateurs l'ignoreront très probablement. Pour une vision rafraîchissante de la convivialité des mots de passe à forte entropie, nous vous recommandons vivement l'ouvrage de Randall Munroe [Password Strength xkcd][15]. Utilisez l'API [Have I Been Pwned API][26] de Troy Hunt pour vérifier les mots de passe des utilisateurs par rapport aux mots de passe compromis lors de violations de données publiques.

    PARTIE VI : Bien plus - Ou : Prévenir les tentatives de connexion rapides

    Tout d'abord, jetez un coup d'œil aux chiffres : [Vitesse de récupération des mots de passe - Combien de temps votre mot de passe résistera-t-il][16]. Si vous n'avez pas le temps de consulter les tableaux de ce lien, en voici la liste :

  3. Il ne faut presque pas de temps pour craquer un mot de passe faible, même si vous le craquez avec un boulier.
  4. Il ne faut presque aucun temps pour craquer un mot de passe alphanumérique de 9 caractères s'il est insensible à la casse.
  5. Il ne faut presque pas de temps pour craquer un mot de passe complexe, composé de symboles, de lettres et de chiffres, en majuscules et en minuscules, s'il s'agit d'un mot de passe de moins de 8 caractères (un PC de bureau peut rechercher tout l'espace des touches jusqu'à 7 caractères en quelques jours, voire quelques heures).
  6. Il faudrait cependant un temps fou pour craquer même un mot de passe à 6 caractères, si vous étiez limité à une tentative par seconde!. Que pouvons-nous apprendre de ces chiffres ? Eh bien, beaucoup, mais nous pouvons nous concentrer sur la partie la plus importante : le fait que la prévention d'un grand nombre de tentatives de connexion successives et rapides (c'est-à-dire l'attaque brute force) n'est pas vraiment difficile. Mais l'empêcher correctement n'est pas aussi facile qu'il n'y paraît. D'une manière générale, vous avez trois possibilités qui sont toutes efficaces contre les attaques par force brute (et les attaques par dictionnaire, mais comme vous utilisez déjà une politique de mots de passe forts, elles ne devraient pas être un problème) :
  • Présenter un CAPTCHA après N tentatives infructueuses (ennuyeux comme l'enfer et souvent inefficace - mais je me répète ici).
  • Verrouiller les comptes et demander une vérification par e-mail après N tentatives infructueuses (c'est une attaque [DoS][17] qui attend de se produire).
  • Et enfin, L'étranglement de la connexion : c'est-à-dire, fixer un délai entre les tentatives après N échecs (oui, les attaques DoS sont toujours possibles, mais au moins elles sont beaucoup moins probables et beaucoup plus compliquées à réaliser). Best practice #1: Un court délai qui augmente avec le nombre de tentatives ratées, comme :
  • 1 tentative ratée = pas de délai
  • 2 tentatives ratées = délai de 2 secondes
  • 3 tentatives ratées = délai de 4 secondes
  • 4 tentatives ratées = délai de 8 secondes
  • 5 tentatives ratées = délai de 16 secondes
  • etc. Une attaque DoS contre ce schéma serait très peu pratique, puisque le temps de verrouillage résultant est légèrement supérieur à la somme des temps de verrouillage précédents. Pour clarifier : le délai n'est pas un délai avant de renvoyer la réponse au navigateur. Il s'agit plutôt d'un délai d'attente ou d'une période réfractaire pendant laquelle les tentatives de connexion à un compte spécifique ou à partir d'une adresse IP spécifique ne seront pas acceptées ou évaluées du tout. En d'autres termes, les informations d'identification correctes ne seront pas renvoyées lors d'une connexion réussie, et les informations d'identification incorrectes ne déclencheront pas d'augmentation du délai. Meilleure pratique #2: Un délai de durée moyenne qui entre en vigueur après N tentatives infructueuses, comme :
  • 1-4 tentatives ratées = pas de délai
  • 5 tentatives ratées = 15-30 min de délai Une attaque DoS contre ce schéma serait assez peu pratique, mais certainement faisable. Il convient également de noter qu'un délai aussi long peut être très gênant pour un utilisateur légitime. Les utilisateurs distraits ne vous apprécieront pas. Meilleure pratique #3: Combiner les deux approches - soit un délai fixe et court qui entre en vigueur après N tentatives infructueuses, comme :
  • 1-4 tentatives ratées = pas de délai
  • 5+ tentatives ratées = délai de 20 secondes Soit un délai croissant avec une limite supérieure fixe, comme :
  • 1 tentative ratée = délai de 5 secondes
  • 2 tentatives ratées = retard de 15 secondes
  • 3+ tentatives ratées = retard de 45 secondes Ce schéma final est tiré des suggestions de meilleures pratiques de l'OWASP (lien 1 de la liste MUST-READ) et devrait être considéré comme une meilleure pratique, même s'il est admis qu'il est un peu restrictif. En règle générale, cependant, je dirais que plus votre politique de mot de passe est stricte, moins vous devez embêter les utilisateurs avec des délais. Si vous exigez des mots de passe forts (alphanumériques sensibles à la casse + chiffres et symboles requis) de plus de 9 caractères, vous pouvez donner aux utilisateurs 2 à 4 tentatives de mot de passe non retardées avant d'activer la restriction. Une attaque DoS contre ce schéma final de limitation de la connexion serait très peu pratique. Et pour finir, autorisez toujours les connexions persistantes (cookies) (et/ou un formulaire de connexion vérifié par CAPTCHA) à passer, afin que les utilisateurs légitimes ne soient même pas retardés pendant que l'attaque est en cours. De cette façon, l'attaque DoS très peu pratique devient une attaque extrêmement peu pratique. De plus, il est judicieux de mettre en place un contrôle plus agressif sur les comptes administrateurs, car ce sont les points d'entrée les plus attrayants.

    PARTIE VII : Attaques par force brute distribuées

    Pour l'anecdote, les attaquants les plus avancés essaieront de contourner la limitation de la connexion en "répartissant leurs activités" :

  • Distribuer les tentatives sur un botnet pour éviter le repérage des adresses IP.
  • Plutôt que de choisir un utilisateur et d'essayer les 50 000 mots de passe les plus courants (ce qu'ils ne peuvent pas faire, à cause de notre étranglement), ils choisiront LE mot de passe le plus courant et l'essaieront contre 50 000 utilisateurs. De cette façon, non seulement ils contournent les mesures de tentatives maximales comme les CAPTCHA et les restrictions de connexion, mais leurs chances de succès augmentent également, puisque le mot de passe le plus courant numéro 1 est beaucoup plus probable que le numéro 49.995.
  • Espacer les demandes de connexion pour chaque compte d'utilisateur, par exemple de 30 secondes, afin de se faufiler sous le radar. Dans ce cas, la meilleure pratique consisterait à enregistrer le nombre d'échecs de connexion, à l'échelle du système, et à utiliser une moyenne courante de la fréquence des mauvaises connexions sur votre site comme base d'une limite supérieure que vous imposerez ensuite à tous les utilisateurs. Trop abstrait ? Laissez-moi reformuler : Supposons que votre site ait connu une moyenne de 120 mauvaises connexions par jour au cours des trois derniers mois. Sur la base de cette moyenne, votre système pourrait fixer la limite globale à trois fois ce chiffre, c'est-à-dire 360 tentatives infructueuses sur une période de 24 heures. Ensuite, si le nombre total de tentatives échouées sur l'ensemble des comptes dépasse ce chiffre en l'espace d'une journée (ou mieux encore, si vous surveillez le taux d'accélération et le déclenchez à partir d'un seuil calculé), il active l'étranglement des connexions à l'échelle du système - ce qui signifie de courts délais pour TOUS les utilisateurs (toujours à l'exception des connexions par cookie et/ou des connexions CAPTCHA de secours). J'ai également posté une question avec [plus de détails et une très bonne discussion sur la façon d'éviter les pièges délicats][18] pour repousser les attaques par force brute distribuées.

    PARTIE VIII : Authentification à deux facteurs et fournisseurs d'authentification

    Les informations d'identification peuvent être compromises, que ce soit par des exploits, des mots de passe écrits et perdus, des ordinateurs portables avec des clés volées ou des utilisateurs qui se connectent à des sites de phishing. Les connexions peuvent être mieux protégées par une authentification à deux facteurs, qui utilise des facteurs hors bande tels que des codes à usage unique reçus par un appel téléphonique, un message SMS, une application ou un dongle. Plusieurs fournisseurs proposent des services d'authentification à deux facteurs. L'authentification peut être entièrement déléguée à un service d'authentification unique, où un autre fournisseur se charge de collecter les informations d'identification. Cela repousse le problème vers un tiers de confiance. Google et Twitter fournissent tous deux des services SSO basés sur des normes, tandis que Facebook propose une solution propriétaire similaire.

    LIENS À LIRE OBLIGATOIREMENT À propos de l'authentification Web

  1. [OWASP Guide To Authentication][6] / [OWASP Authentication Cheat Sheet][19] (en anglais)
  2. [Dos and Don'ts of Client Authentication on the Web (document de recherche du MIT très lisible)] [20].
  3. [Wikipedia : cookie HTTP] [21]
  4. [Questions de connaissances personnelles pour l'authentification de secours : Questions de sécurité à l'ère de Facebook (document de recherche très lisible de Berkeley)] [22]. [1] : https://en.wikipedia.org/wiki/Transport_Layer_Security [2] : https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange [3] : https://stackoverflow.com/questions/1380168/does-it-make-security-sense-to-hash-password-on-client-end [4] : https://en.wikipedia.org/wiki/CAPTCHA [5] : https://en.wikipedia.org/wiki/OWASP [6] : https://www.owasp.org/index.php/Authentication_Cheat_Sheet [7] : https://en.wikipedia.org/wiki/ReCAPTCHA [8] : https://en.wikipedia.org/wiki/Rainbow_table [9] : https://www.owasp.org/index.php/Session_fixation [10] : https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence [11] : http://www.whatsmypass.com/?p=415 [12] : https://en.wikipedia.org/wiki/Password_strength#NIST_Special_Publication_800-63 [13] : https://cubicspot.blogspot.com/2012/01/how-to-calculate-password-strength-part.html [14] : https://blogs.dropbox.com/tech/2012/04/zxcvbn-realistic-password-strength-estimation/ [15] : https://xkcd.com/936/ [16] : https://www.lockdown.co.uk/?pg=combi&s=articles [17] : https://en.wikipedia.org/wiki/Denial-of-service_attack [18] : https://stackoverflow.com/questions/479233/what-is-the-best-distributed-brute-force-countermeasure [19] : https://www.owasp.org/index.php/Authentication_Cheat_Sheet [20] : https://pdos.csail.mit.edu/papers/webauth:sec10.pdf [21] : https://en.wikipedia.org/wiki/HTTP_cookie#Drawbacks_of_cookies [22] : https://cups.cs.cmu.edu/soups/2008/proceedings/p13Rabkin.pdf [23] : https://security.stackexchange.com/a/31846/8340 [24] : https://en.wikipedia.org/wiki/Key_derivation_function [25] : https://en.wikipedia.org/wiki/Key_stretching [26] : https://haveibeenpwned.com/API/ [27] : https://letsencrypt.org/
Commentaires (70)

Article définitif

Envoi d'informations d'identification

Le seul moyen pratique d'envoyer des informations d'identification de manière 100% sécurisée est d'utiliser [SSL][1]. L'utilisation de JavaScript pour hacher le mot de passe n'est pas sûre. Pièges courants pour le hachage de mot de passe côté client :

  • Si la connexion entre le client et le serveur n'est pas cryptée, tout ce que vous faites est [vulnérable aux attaques de type man-in-the-middle][2]. Un attaquant pourrait remplacer le javascript entrant pour casser le hachage ou envoyer toutes les informations d'identification à son serveur, il pourrait écouter les réponses du client et se faire passer pour un utilisateur parfait, etc. etc. Le SSL avec des autorités de certification de confiance est conçu pour prévenir les attaques MitM.
  • Le mot de passe haché reçu par le serveur est [moins sûr][3] si vous ne faites pas de travail supplémentaire et redondant sur le serveur. Il existe une autre méthode sécurisée appelée SRP, mais elle est brevetée (bien qu'elle soit [sous licence libre][4]) et il existe peu de bonnes implémentations disponibles.

    Stockage des mots de passe

    Ne stockez jamais les mots de passe en texte clair dans la base de données. Même si vous ne vous souciez pas de la sécurité de votre propre site. Supposons que certains de vos utilisateurs réutilisent le mot de passe de leur compte bancaire en ligne. Stockez donc le mot de passe haché, et jetez l'original. Et assurez-vous que le mot de passe n'apparaît pas dans les journaux d'accès ou les journaux d'application. L'OWASP [recommande l'utilisation d'Argon2] (https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet#Impose_infeasible_verification_on_attacker) comme premier choix pour les nouvelles applications. S'il n'est pas disponible, il faut utiliser PBKDF2 ou scrypt à la place. Et enfin, si aucun des éléments ci-dessus n'est disponible, utilisez bcrypt. Les hachages en eux-mêmes sont également peu sûrs. Par exemple, des mots de passe identiques signifient des hachages identiques - ce qui fait des tables de consultation de hachages un moyen efficace de craquer beaucoup de mots de passe à la fois. Au lieu de cela, stockez le hachage salé. Un sel est une chaîne ajoutée au mot de passe avant le hachage - utilisez un sel différent (aléatoire) par utilisateur. Le sel est une valeur publique, vous pouvez donc le stocker avec le hachage dans la base de données. Voir ici pour plus d'informations à ce sujet. Cela signifie que vous ne pouvez pas envoyer à l'utilisateur ses mots de passe oubliés (car vous n'avez que le hachage). Ne réinitialisez pas le mot de passe de l'utilisateur à moins que vous n'ayez authentifié l'utilisateur (les utilisateurs doivent prouver qu'ils sont capables de lire les courriels envoyés à l'adresse électronique stockée (et validée)).

    Questions de sécurité

    Les questions de sécurité ne sont pas sûres - évitez de les utiliser. Pourquoi ? Tout ce que fait une question de sécurité, un mot de passe le fait mieux. Lisez PART III : Using Secret Questions dans [@Jens Roland answer][6] ici dans ce wiki.

    Cookies de session

    Après que l'utilisateur s'est connecté, le serveur lui envoie un cookie de session. Le serveur peut récupérer le nom d'utilisateur ou l'identifiant à partir du cookie, mais personne d'autre ne peut générer un tel cookie (TODO expliquer les mécanismes). [Les cookies peuvent être détournés][7] : ils ne sont aussi sûrs que le reste de la machine du client et les autres communications. Ils peuvent être lus à partir du disque, reniflés dans le trafic réseau, soulevés par une attaque de type cross-site scripting, hameçonnés à partir d'un DNS empoisonné afin que le client envoie ses cookies aux mauvais serveurs. N'envoyez pas de cookies persistants. Les cookies doivent expirer à la fin de la session du client (fermeture du navigateur ou départ de votre domaine). Si vous souhaitez authentifier vos utilisateurs, vous pouvez définir un cookie persistant, mais il doit être distinct d'un cookie de session complète. Vous pouvez définir un indicateur supplémentaire indiquant que l'utilisateur s'est connecté automatiquement et qu'il doit se connecter réellement pour les opérations sensibles. Cette méthode est populaire auprès des sites d'achat qui souhaitent vous offrir une expérience d'achat transparente et personnalisée tout en protégeant vos données financières. Par exemple, lorsque vous revenez sur le site d'Amazon, il vous montre une page qui donne l'impression que vous êtes connecté, mais lorsque vous allez passer une commande (ou modifier votre adresse de livraison, votre carte de crédit, etc.), il vous demande de confirmer votre mot de passe. Les sites Web financiers tels que les banques et les cartes de crédit, en revanche, ne contiennent que des données sensibles et ne devraient pas autoriser la connexion automatique ou un mode de sécurité faible.

    Liste de ressources externes

Commentaires (5)

Tout d'abord, une mise en garde importante : cette réponse n'est pas la meilleure pour cette question exacte. Elle ne doit absolument pas être la première réponse !

Je vais mentionner le [BrowserID][1] proposé par Mozilla (ou peut-être plus précisément, le [Verified Email Protocol][2]) dans l'esprit de trouver une voie de mise à niveau vers de meilleures approches d'authentification à l'avenir.

Je résume la situation de la manière suivante :

  1. Mozilla est une organisation à but non lucratif avec des [valeurs][3] qui s'alignent bien avec la recherche de bonnes solutions à ce problème.
  2. La réalité d'aujourd'hui est que la plupart des sites web utilisent l'authentification par formulaire.
  3. L'authentification par formulaire présente un inconvénient majeur, à savoir un risque accru de [phishing][4]. Les utilisateurs sont invités à saisir des informations sensibles dans une zone contrôlée par une entité distante, plutôt que dans une zone contrôlée par leur agent utilisateur (navigateur).
  4. Étant donné que les navigateurs bénéficient d'une confiance implicite (l'idée même d'un agent utilisateur est d'agir au nom de l'utilisateur), ils peuvent contribuer à améliorer cette situation.
  5. La principale force qui freine les progrès dans ce domaine est le [blocage du déploiement][5]. Les solutions doivent être décomposées en étapes qui apportent un avantage progressif par elles-mêmes.
  6. La méthode décentralisée la plus simple pour exprimer une identité qui est intégrée dans l'infrastructure Internet est le nom de domaine.
  7. Comme deuxième niveau d'expression de l'identité, chaque domaine gère son propre ensemble de comptes.
  8. La forme "account@domain" est concise et supportée par une large gamme de protocoles et de schémas URI. Un tel identifiant est, bien sûr, le plus universellement reconnu comme une adresse électronique.
  9. Les fournisseurs de courrier électronique sont déjà de facto les principaux fournisseurs d'identité en ligne. Les flux actuels de réinitialisation des mots de passe vous permettent généralement de prendre le contrôle d'un compte si vous pouvez prouver que vous contrôlez l'adresse électronique associée à ce compte.
  10. Le protocole Verified Email a été proposé pour fournir une méthode sécurisée, basée sur la cryptographie à clé publique, afin de rationaliser le processus permettant de prouver au domaine B que vous avez un compte sur le domaine A.
  11. Pour les navigateurs qui ne prennent pas en charge le protocole Verified Email (actuellement tous), Mozilla fournit un shim qui implémente le protocole dans un code JavaScript côté client.
  12. Pour les services de messagerie qui ne prennent pas en charge le protocole Verified Email Protocol, ce dernier permet à des tiers d'agir en tant qu'intermédiaire de confiance, en affirmant qu'ils ont vérifié la propriété d'un compte par un utilisateur. Il n'est pas souhaitable d'avoir un grand nombre de ces tiers ; cette capacité est destinée uniquement à permettre une mise à niveau, et il est de loin préférable que les services de messagerie fournissent eux-mêmes ces affirmations.
  13. Mozilla offre son propre service pour agir comme un tel tiers de confiance. Les fournisseurs de services (c'est-à-dire les parties utilisatrices) mettant en œuvre le protocole de courriel vérifié peuvent choisir de faire confiance aux affirmations de Mozilla ou non. Le service de Mozilla vérifie la propriété du compte des utilisateurs en utilisant le moyen conventionnel d'envoyer un courriel avec un lien de confirmation.
  14. Les fournisseurs de services peuvent, bien entendu, proposer ce protocole en option en plus de toute autre méthode d'authentification qu'ils souhaiteraient offrir.
  15. Un grand avantage de l'interface utilisateur recherché ici est le "sélecteur d'identité". Lorsqu'un utilisateur visite un site et choisit de s'authentifier, son navigateur lui présente une sélection d'adresses électroniques ("personnelles", "professionnelles", "politiques", etc.
  16. Un autre avantage important de l'interface utilisateur recherché dans le cadre de cet effort est [d'aider le navigateur à en savoir plus sur la session de l'utilisateur][6] - c'est-à-dire sous quel nom il est actuellement connecté, principalement - de sorte qu'il puisse l'afficher dans le chrome du navigateur.
  17. En raison de la nature distribuée de ce système, il évite l'enfermement dans des sites majeurs comme Facebook, Twitter, Google, etc. Tout individu peut posséder son propre domaine et donc agir comme son propre fournisseur d'identité.

Il ne s'agit pas à proprement parler d'une "authentification par formulaire pour les sites web". Mais il s'agit d'un effort pour passer de la norme actuelle d'authentification basée sur des formulaires à quelque chose de plus sûr : l'authentification supportée par le navigateur.

[1] : https://browserid.org/ [2] : https://wiki.mozilla.org/Identity/Verified_Email_Protocol/Latest [3] : http://www.mozilla.org/about/manifesto.en.html [4] : http://en.wikipedia.org/wiki/Phishing [5] : http://www.w3.org/2011/identity-ws/papers/idbrowser2011_submission_10.pdf [6] : https://wiki.mozilla.org/Identity/Verified_Email_Protocol/Latest-Session

Commentaires (2)