Je souhaite réécrire mes scripts de connexion pour les sites Web des clients afin de les rendre plus sécurisés. Je veux savoir quelles meilleures pratiques je peux mettre en œuvre dans ce domaine. Les panneaux de contrôle protégés par mot de passe sont nombreux, mais très peu semblent implémenter les meilleures pratiques en termes d'écriture de code, de vitesse et de sécurité.
J'utiliserai PHP et une base de données MYSQL.
J'avais l'habitude d'utiliser md5, mais je vois que sha256 ou sha512 serait mieux (avec du hachage sécurisé et du sel).
Certains scripts de connexion enregistrent l'adresse IP tout au long de la session ou même l'agent utilisateur, mais je veux éviter cela car il n'est pas compatible avec les serveurs proxy.
Je suis également un peu en retard sur les meilleures pratiques d'utilisation des sessions en PHP 5 (la dernière fois que j'ai lu était PHP 4), donc certaines des meilleures pratiques avec cela seraient utiles.
Merci.
la source
Réponses:
Le mieux est de ne pas réinventer la roue. Mais, je comprends, dans le monde PHP, il peut être difficile de trouver un composant de haute qualité qui le fait déjà (même je suis presque sûr que les frameworks implémentent de telles choses et que leurs implémentations sont déjà testées, solides, révisées par le code, etc. )
Si, pour certaines raisons, vous ne pouvez pas utiliser un framework, voici quelques suggestions:
Suggestions liées à la sécurité
Utilisez PBKDF2 ou Bcrypt si vous le pouvez . C'est fait pour ça.
Justification: les deux algorithmes peuvent ralentir arbitrairement le processus de hachage, ce qui est exactement ce que vous voulez lorsque vous hachez des mots de passe (des alternatives plus rapides signifient une force brute plus facile). Idéalement, vous devez ajuster les paramètres afin que le processus devienne de plus en plus lent au fil du temps sur le même matériel, tandis qu'un nouveau matériel plus rapide est publié.
Si vous ne pouvez pas, au moins n'utilisez pas MD5 / SHA1. Jamais. Oublie ça . Utilisez SHA512 à la place, par exemple. Utilisez aussi du sel.
Justification: MD5 et SHA1 sont trop rapides. Si l'attaquant a accès à votre base de données contenant les hachages et possède une machine (pas même particulièrement) puissante, le forçage brutal d'un mot de passe est rapide et facile. S'il n'y a pas de sels, les chances que l'attaquant trouve le mot de passe réel augmentent (ce qui pourrait nuire davantage si le mot de passe était réutilisé ailleurs).
En PHP 5.5.0 et versions ultérieures, utilisez
password_hash
etpassword_verify
.Justification: appeler une fonction fournie par le framework est facile, donc le risque de faire une erreur est réduit. Avec ces deux fonctions, vous n'avez pas à penser à différents paramètres tels que le hachage. La première fonction renvoie une seule chaîne qui peut ensuite être stockée dans la base de données. La deuxième fonction utilise cette chaîne pour la vérification du mot de passe.
Protégez-vous de la force brute . Si l'utilisateur soumet un mauvais mot de passe alors qu'il a déjà soumis un autre mauvais mot de passe il y a 0,01 seconde, c'est une bonne raison de le bloquer. Alors que les êtres humains peuvent saisir rapidement, ils peuvent probablement pas que rapides.
Une autre protection serait de fixer une limite de pannes par heure. Si l'utilisateur a soumis 3600 mots de passe erronés en une heure, 1 mot de passe par seconde, il est difficile de croire qu'il s'agit d'un utilisateur légitime.
Raisonnement: si vos mots de passe sont hachés de manière non sécurisée, la force brute peut être très efficace. Si les mots de passe sont stockés en toute sécurité, la force brute gaspille toujours les ressources et la bande passante du réseau de votre serveur, ce qui réduit les performances des utilisateurs légitimes. La détection de la force brute n'est pas facile à développer et à obtenir, mais pour tout système, mais minuscule, cela en vaut la peine.
Ne demandez pas à vos utilisateurs de changer leur mot de passe toutes les quatre semaines. Ceci est extrêmement ennuyeux et diminue la sécurité, car il encourage la sécurité post-it.
Justification: l'idée que forcer les mots de passe à changer toutes les n semaines protège le système de la force brute est fausse. Les attaques par force brute réussissent généralement en quelques secondes, minutes, heures ou jours, ce qui rend les changements de mot de passe mensuels non pertinents. D'un autre côté, les utilisateurs se souviennent mal des mots de passe. Si, par ailleurs, ils doivent les changer, ils tenteront soit d'utiliser des mots de passe très simples, soit de simplement noter leurs mots de passe sur les post-its.
Auditez tout, à chaque fois. Stockez les ouvertures de session, mais ne stockez jamais les mots de passe dans le journal d'audit. Assurez-vous que le journal d'audit ne peut pas être modifié (c'est-à-dire que vous pouvez ajouter des données à la fin, mais pas modifier les données existantes). Assurez-vous que les journaux d'audit sont soumis à une sauvegarde régulière. Idéalement, les journaux devraient être stockés sur un serveur dédié avec des accès très restrictifs: si un autre serveur est piraté, l'attaquant ne pourra pas effacer les journaux pour cacher sa présence (et le chemin emprunté pendant l'attaque).
Ne me souviens pas des informations d'identification de l'utilisateur dans les cookies, sauf si l'utilisateur demande à le faire (la case "Se souvenir de moi" doit être décochée par défaut pour éviter les erreurs humaines).
Suggestions de facilité d'utilisation
<span/>
. Les navigateurs ne peuvent pas remplir le champ de mot de passe dans ce cas (au moins Firefox ne peut pas le faire), il oblige donc à se déconnecter, puis à se connecter avec un formulaire ordinaire, rempli par le navigateur.la source
bcrypt
est fait par des personnes hautement qualifiées. Il est également testé, révisé, etc. Il n'y a donc aucune raison d'implémenter la même chose vous-même. C'est comme créer votre propre algorithme de cryptographie pour votre site Web. * "Pourquoi pas md5 / sha1?": Voir par exemple en.wikipedia.org/wiki/MD5#Securitybcrypt
si possible. Sinon, utilisez un autre type de hachage itéré.mysql_real_escape_string
. N'utilisez jamais la concaténation de chaînes pour créer votre requête. Utilisez des requêtes préparées et paramétrées. La plupart, sinon la totalité, des pilotes DB pour PHP le prennent en charge. Si vous ne savez pas comment le faire, passer un peu de temps à apprendre commentprepare
,bind
et enexecute
utilisant tous les DB que vous utilisez. C'est le seul moyen sûr de se prémunir contre l'injection SQL. PDO prend cela en charge.la source
mysql_real_escape_string
est une fausse sécurité - ce n'est pas une garantie. Les requêtes paramétrées le sont.Utilisez un hachage unidirectionnel salé (de préférence SHA512 en utilisant http://au2.php.net/manual/en/function.hash.php ) ... de cette façon, si quelqu'un pirate votre base de données, même s'il connaît le sel , ils ne peuvent pas extraire les mots de passe (sans une table arc-en-ciel, ce qui serait trop long pour SHA512).
Utilisez HTTPS.
N'envoyez pas de confirmation de nom d'utilisateur / mot de passe par e-mail à l'utilisateur lors de son inscription.
Si vous autorisez les cookies pour «se souvenir de moi» - ajoutez une connexion supplémentaire pour accéder aux fonctions d'administration et de modification de profil.
Si un utilisateur obtient un mot de passe erroné, ne dites pas qu'il s'est trompé de mot de passe (disons qu'il a toujours eu le 'nom d'utilisateur ou mot de passe incorrect') - de cette façon, moins d'indices sur les noms d'utilisateur valides.
Essayez d'implémenter le nom d'écran par rapport à la connexion - de cette façon, moins d'utilisateurs afficheront leur nom de connexion sur les listes d'utilisateurs.
la source
la source
Voici un conseil: assurez-vous que vos cookies ne sont pas accessibles avec JS pour empêcher le vol, voir l'article Protéger vos cookies: article HttpOnly de Jeff Atwood
la source