URL: https://linuxfr.org/news/la-securite-dans-le-developpement Title: La sécurité dans le développement Authors: claudex Benoît Sibaud, Al, Bruno Michel, Pierre Jarillon, baud123, Nÿco, Benoît, maboiteaspam et freem Date: 2012年09月16日T15:53:33+02:00 License: CC By-SA Tags: gestionnaire_de_mots_de_passe Score: 21 Voici une dépêche qui regroupe quelques bonnes pratiques sur les mots de passe et la gestion des données dans une application. Elle est loin d'être exhaustive et, donc, n'hésitez pas à la compléter dans les commentaires ou d'écrire la suite dans l'[espace de rédaction collaborative](http://linuxfr.org/redaction). ---- [Écrire la suite](http://linuxfr.org/redaction) ---- # Les mots de passe ## Stockage des mots de passe sur le serveur La principale préoccupation est de limiter les dégâts qui pourraient être causés si un attaquant (ou un admin malveillant) parvenait à lire la base de données de mots de passe. Pour cela, il faut ne surtout pas stocker les mots de passe en clair, mais les transformer en utilisant une [fonction de hachage cryptographique](http://fr.wikipedia.org/wiki/fonction de hachage cryptographique "Définition Wikipédia") préalablement à l'enregistrement. Également connues sous le nom de « fonctions à sens unique », ces fonctions sont faites pour qu'il soit difficile de retrouver leur entrée (le mot de passe en clair) à partir de leur sortie (le mot de passe haché). Contrairement aux fonctions de chiffrement, les fonctions de hachage ne sont pas paramétrées par une clé secrète et ne sont pas bijectives. Grâce à cela, les données stockées permettent uniquement de _vérifier_ facilement qu'un mot de passe entré par l'utilisateur est le bon, mais pas de le retrouver. Comme il est possible par bruteforce (ou des techniques plus raffinées) de retrouver le mot de passe en clair et qu'il existe des tables précalculées ([Rainbow table](http://fr.wikipedia.org/wiki/Rainbow table "Définition Wikipédia")) pour les principaux algorithmes, il est aussi conseillé de saler les mots de passe. Cela consiste à ajouter des bits aléatoirement générés à la création du login et les ajouter au mot de passe avant d'utiliser la fonction de hachage; cela rend l'utilisation des tables précalculées inutile et l'aspect unique par utilisateur permet d'éviter que deux utilisateurs avec le même mot de passe aient le même résultat de la fonction de hachage. Avec la puissance de plus en plus importante des ordinateurs, même des hashs (résultat d'une fonction de hachage) salés peuvent permettre de retrouver rapidement les mots de passe les plus courts. Il ne faut donc pas utiliser une fonction de hachage prévue pour traiter rapidement de grandes quantités de données ([MD5](http://fr.wikipedia.org/wiki/MD5 "Définition Wikipédia"), [SHA-512](http://fr.wikipedia.org/wiki/SHA-512 "Définition Wikipédia")...) mais des algorithmes prévus pour être lents ([bcrypt](http://fr.wikipedia.org/wiki/en:bcrypt "Définition Wikipédia")...). L'intérêt est de ralentir le déchiffrage de votre base de données, et, à moins que vous n'authentifiez des milliers d'utilisateurs par seconde (ce qui peut arriver en cas d'attaque DDoS, il est donc bon de s'en protéger), ça ne devrait pas poser de problème de performances sur votre serveur. ## Du côté client Il faut éviter de stocker des mots de passe en clair sur les postes des utilisateurs, cela permettrait à un intrus ou à un virus de les lire. On peut soit les demander à l'utilisateur au démarrage de l'application ou, s'il y en a plusieurs, les conserver chiffrés avec une clef basée sur un mot de passe demandé à l'utilisateur ou en se basant sur un gestionnaire de mots de passe du système tel que KWallet ou Gnome-keyring. # Données ## Données « externes » Les données externes concernent bien sûr les saisies de l'opérateur, mais également celles provenant des autres programmes, du réseau, de variables d'environnement... En fait, toute donnée qui a eu une relation avec un autre binaire (les périphériques matériels, donc l'utilisateur, sont après tout perçus au travers des pilotes, qui sont des binaires...) doit être considérée comme externe. Les bibliothèques sont idéalement à inclure (mais cela représente certainement trop de travail pour être réellement fait) : un simple changement de version peut amener un changement de comportement, qui peut invalider les données et ainsi causer des vulnérabilités. Ce changement de comportement n'impliquant pas nécessairement une rupture de l'ABI (_application binary interface_), on ne peut se fier au système d'exploitation. Mais le plus probable est une version compromise d'une des dépendances: il suffit qu'un attaquant ait indiqué au système qu'il faut utiliser une version qu'il a lui-même altérée de la bibliothèque (changement du PATH ou LDPATH, en fonction du système d'exploitation attaqué). Ces données doivent être systématiquement vérifiées et protégées, car elles sont un important vecteur d'attaque. Quelques exemples: * buffer overflow : insertion de plus de données que le programme ne l'avait prévu, afin de modifier le binaire lors de son exécution. L'usage de conteneurs dynamiques (listes chaînées, par exemple) permet de réduire drastiquement les risques de ce genre d'attaques, mais impliquent un coût en ressources (temps processeur et occupation mémoire notamment) plus élevé. Ces conteneurs ne sont donc pas la panacée. * injection de code : lors de l'usage d'un langage de script (SQL ou PHP par exemple) il est possible d'insérer le caractère permettant de signaler à l'interpréteur la fin d'une chaîne de caractère, puis d'insérer du code directement. Cette attaque est très simple à réaliser. ## Données « internes » Les autres données nécessitent aussi des vérifications, sauf si elles garantissent leur réussite ou si leur état reste valide malgré l'échec d'une opération sur elles (un [article intéressant à ce sujet](http://www.boost.org/community/exception_safety.html)). Lorsque ces garanties ne sont pas présentes, il faut systématiquement vérifier que tout s'est déroulé comme prévu ou que la donnée est toujours dans un état valide. Un exemple d'échec pourrait être un élément qui n'est pas correctement initialisé par manque de mémoire, laissant l'objet qui le nécessite dans un état indéterminé. Ne pas effectuer ces vérifications expose à un risque de plantage, et qui dit risque de plantage dit possibilité d'attaque.