96 votes

Nettoyage des mots de passe des utilisateurs

Comment dois-je échapper ou nettoyer les mots de passe fournis par les utilisateurs avant de les hacher et de les stocker dans ma base de données ?

Lorsque les développeurs PHP envisagent de hacher les mots de passe des utilisateurs à des fins de sécurité, ils ont souvent tendance à penser à ces mots de passe comme à toute autre donnée fournie par l'utilisateur. Ce sujet revient souvent dans les questions PHP liées au stockage des mots de passe ; le développeur veut souvent nettoyer le mot de passe en utilisant des fonctions telles que escape_string() (dans diverses itérations), htmlspecialchars() , addslashes() et autres avant de les hacher et de les stocker dans la base de données.

98voto

Jay Blanchard Points 6238

Vous ne devez jamais échapper, couper ou utiliser tout autre mécanisme de nettoyage sur les mots de passe que vous allez hacher avec la méthode de PHP. password_hash() pour un certain nombre de raisons, dont la plus importante est que le nettoyage supplémentaire du mot de passe nécessite un code supplémentaire inutile.

Vous soutiendrez (et vous le voyez dans chaque message où les données des utilisateurs sont acceptées pour être utilisées dans vos systèmes) que nous devrions nettoyer toutes les entrées des utilisateurs et vous auriez raison pour chaque autre élément d'information que nous acceptons de nos utilisateurs. Les mots de passe sont différents. Les mots de passe hachés ne peuvent présenter aucune menace d'injection SQL, car la chaîne est transformée en hachage avant d'être stockée dans la base de données.

Le hachage d'un mot de passe consiste à sécuriser le mot de passe pour le stocker dans votre base de données. La fonction de hachage ne donne aucune signification particulière aux octets, de sorte qu'aucun nettoyage de son entrée n'est nécessaire pour des raisons de sécurité.

Si vous suivez les mantras consistant à permettre aux utilisateurs d'utiliser les mots de passe / phrases qu'ils désirent et que vous ne pas limiter les mots de passe En autorisant n'importe quelle longueur, n'importe quel nombre d'espaces et n'importe quel caractère spécial, le hachage rendra le mot de passe/la phrase de passe sûr, quel que soit le contenu du mot de passe. À l'heure actuelle, le hachage le plus courant (par défaut), PASSWORD_BCRYPT transforme le mot de passe en une chaîne de 60 caractères contenant un sel aléatoire ainsi que les informations du mot de passe haché et un coût (le coût algorithmique de la création du hachage) :

PASSWORD_BCRYPT est utilisé pour créer de nouveaux hachages de mots de passe en utilisant l'algorithme CRYPT_BLOWFISH. Le résultat sera toujours un hachage utilisant le format cryptographique "$2y$", qui a toujours une largeur de 60 caractères.

L'espace requis pour le stockage du hachage est susceptible de changer au fur et à mesure que différentes méthodes de hachage sont ajoutées à la fonction. Il est donc toujours préférable d'opter pour un type de colonne plus grand pour le hachage stocké, par exemple VARCHAR(255) o TEXT .

Vous pourriez utiliser une requête SQL complète comme mot de passe et elle serait hachée, ce qui la rendrait inexécutable par le moteur SQL, par exemple,

SELECT * FROM `users`;

Il pourrait être haché en $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

Voyons comment différentes méthodes de désinfection affectent le mot de passe -

Le mot de passe est I'm a "dessert topping" & a <floor wax>! (Il y a 5 espaces à la fin du mot de passe qui ne sont pas affichés ici).

Lorsque nous appliquons les méthodes d'élagage suivantes, nous obtenons des résultats très différents :

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

Résultats :

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

Que se passe-t-il lorsque nous les envoyons à password_hash() ? Ils sont tous hachés, tout comme la requête ci-dessus. Le problème se pose lorsque l'on essaie de vérifier le mot de passe. Si nous utilisons une ou plusieurs de ces méthodes, nous devons les réemployer avant de les comparer à password_verify() . Les éléments suivants échouent :

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

Vous devrez soumettre le mot de passe affiché à la méthode de nettoyage que vous avez choisie avant d'en utiliser le résultat pour la vérification du mot de passe. Il s'agit d'une série d'étapes inutiles qui n'amélioreront pas le hachage.


Vous utilisez une version de PHP inférieure à 5.5 ? Vous pouvez utiliser le password_hash() pack de compatibilité .

Vous ne devriez vraiment pas utiliser Hachage MD5 des mots de passe .

36voto

legoscia Points 12766

Avant de hacher le mot de passe, vous devriez le normaliser comme décrit dans la section section 4 du RFC 7613 . En particulier :

  1. Règle de mappage supplémentaire : Toute instance d'espace non-ASCII DOIT être mise en correspondance avec l'espace ASCII (U+0020). être mappée en espace ASCII (U+0020) ; un espace non-ASCII est tout point de code Unicode Un espace non-ASCII est tout point de code Unicode ayant une catégorie générale Unicode de "Zs" (à l'exception de U+0020). l'exception de U+0020).

et :

  1. Règle de normalisation : La forme de normalisation C d'Unicode (NFC) DOIT être appliquée à tous les caractères.

Cela permet de garantir que si l'utilisateur tape le même mot de passe mais en utilisant une méthode de saisie différente, le mot de passe sera quand même accepté.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X