Détails
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" ; 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")
- 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 :
- Suggérant des sous-thèmes
- Soumettant de bons articles sur ce sujet
- 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
5304
3
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.
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 :
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
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 :
@
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.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