web-dev-qa-db-fra.com

Comment éviter de mettre le mot de passe de la base de données dans un script Perl?

J'ai un script Perl connecté qui se connecte à notre base de données et effectue différents types de recherches et de vérifications d'intégrité. Le script original a été écrit par quelqu'un il y a longtemps. Mon travail consiste à y apporter des modifications. Mais je n'aime vraiment pas regarder le username="foo", password="bar" paramètres codés en dur pour accéder à la base de données.

Il doit y avoir un moyen plus sûr de le faire. Tout ce à quoi je pourrais penser pour l'instant est de commenter le travail cron, de supprimer la ligne du script qui avait le mot de passe et de commencer à réfléchir à la façon de rendre cela plus sûr. Mais en attendant, les choses que le script doit faire à la main.

Des idées?

23
Luke Sheppard

La méthode standard consiste à placer les informations d'identification dans un fichier de configuration et à essayer de protéger le fichier de configuration contre une lecture plus lisible que le fichier Perl. Cela offre une augmentation modérée de la sécurité; par exemple, le code peut être en contrôle de source et accessible aux développeurs, le fichier de configuration ne le serait pas. Le code doit être dans la racine cgi du serveur Web, et éventuellement téléchargeable sous certaines erreurs de configuration, et le fichier de configuration n'a pas besoin de l'être.

La manière ambitieuse consiste à chiffrer de manière réversible les informations d'identification et à les placer dans un fichier de configuration. Bien sûr, tout ce qui est crypté de manière réversible peut être décrypté. L'application BladeLogic a fait cela, et c'était trivial (<1 jour) pour moi de décompiler leur Java assez pour découvrir la fonction pour décrypter les informations d'identification et l'utiliser pour les décrypter à ma satisfaction Pas une marque contre eux, c'est juste le nom du jeu crypté réversible.

Une autre option consiste à utiliser l'autorisation basée sur le système d'exploitation de concert avec des restrictions de base de données strictement limitées. Par exemple, limitez l'accès de l'utilisateur du client de base de données à un ensemble de procédures stockées pour limiter les risques d'abus et autorisez cet utilisateur à accéder à la base de données sans mot de passe. Cela ne fonctionne pas si vous faites du client-serveur sur le réseau, ce qui limite la fréquence à laquelle cela est utile. En outre, les gens ont tendance à regarder plus avec méfiance l'accès des utilisateurs du système d'exploitation "sans mot de passe" qu'à écrire le mot de passe à volonté. Ce n'est pas complètement logique, mais il existe des normes qui stipulent que tous les utilisateurs de bases de données doivent avoir des mots de passe, c'est tout.

24
gowenfawr

Je passe souvent le mot de passe au script dans une variable d'environnement de sorte que le script n'a pas besoin d'avoir accès à l'emplacement sécurisé qui contient le mot de passe.

PASSWORD=`cat passwd_file`  Perl_script.pl

puis le script lit le mot de passe

my $password = $ENV{'PASSWORD'}

des points bonus si le script Perl baisse les privilèges

8
Arthur Ulfeldt

Comme d'autres l'ont déjà dit, mettez les informations d'identification dans un fichier séparé que le script chargera. Les risques d'avoir le mot de passe dans le script incluent son exposition au surf sur l'épaule, son implication dans des systèmes de contrôle de révision ou des systèmes de gestion de configuration et distribué bien au-delà de ce qu'il devrait être, en copiant accidentellement vers un autre emplacement lors de la réutilisation d'une partie du code, etc.

Le fichier d'informations d'identification doit disposer des autorisations minimales nécessaires. Il ne devrait pas être inclus ou traité différemment par les systèmes de gestion de configuration.

Si disponible, examinez l'utilisation d'une fonctionnalité de système d'exploitation qui limite l'accès au fichier d'informations d'identification plus que les autorisations. Par exemple, AppArmor ou SELinux sous Linux peut restreindre l'accès au fichier d'informations d'identification au seul script qui en a besoin. Cela ne protège que contre un attaquant qui ne peut pas prendre le contrôle du script légitime, alors assurez-vous que le script légitime n'appartient pas à l'utilisateur qui l'exécute (il s'agit d'une recommandation générale: ne pas avoir de programmes exécutables appartenant à l'utilisateur qui les exécute). ).

Le consensus semble être:

  1. Le mot de passe doit être dans un fichier séparé, ne faisant pas partie du contrôle de version, et protégé avec des autorisations plus restrictives que celle du script.
  2. Le cryptage du mot de passe stocké est une perte de temps car le script doit de toute façon pouvoir décrypter le mot de passe.

Mais je pense à ajouter un troisième contrôle en plus de ceux-ci: le contrôle d'accès basé sur le temps (temporel) pourrait aussi aider un peu ici. Limiter la durée pendant laquelle le mot de passe en texte clair est disponible pour les utilisateurs privilégiés inférieurs ajouterait une autre couche (bien que petite) de contrôle d'accès entre le mot de passe et tout attaquant local.

Mon idée est que root possède le fichier de mot de passe, défini sur mode 04 . Et puis avoir un cronjob racine qui fait un chmod 0404 sur le fichier de mot de passe juste avant le cronjob de privilèges inférieurs qui exécute le script. À un intervalle spécifié plus tard (si tout va bien après l'exécution du script), un second cronjob racine fait un chmod 0400 sur le fichier de mot de passe. Tout cela suppose que le script n'a besoin du mot de passe que pour une période inférieure à toujours . Vos réflexions sur ce schéma?

2
Luke Sheppard

Serait-ce une solution appropriée:

  1. Le mot de passe est stocké dans un programme C/C++ compilé qui est obscurci comme ceci: char password [100]; mot de passe [0] = 'a'; mot de passe [1] = 'b'; mot de passe [2] = 'c'; mot de passe [3] = '\ 0';

Ou une autre façon de masquer le mot de passe. (le mot de passe ne doit pas être disponible en exécutant des "chaînes" sur l'exécutable)

  1. Le programme C/C++ renvoie uniquement le mot de passe aux scripts enregistrés et approuvés: A. Obtenez ppid et vérifiez/proc // cmdline,/proc // comm, etc. B. Obtenez l'inode du script de l'appelant et comparez avec l'identité enregistrée, pour vous assurer le script n'a pas été modifié.
0

J'aime mettre des configs dans ~/config/appname et avoir une configuration générique pour ma connexion mysql locale (ou toute autre). Si vous ne voulez pas donner à votre domicile une autorisation X et exécuter l'application en tant qu'utilisateur différent, ayez un dossier de configuration standard quelque part. Je fais cela pour ne pas empaqueter accidentellement ou donner des mots de passe ou des noms d'utilisateur à d'autres programmeurs. Je ne pense pas que ce soit un gros problème, mais mon patron est un monstre de sécurité et c'est une bonne habitude, surtout lorsque vous publiez quelque chose sur le Web.

Il serait sage d'écrire un oneliner ou un twoliner standard pour vos fichiers de configuration et de les copier/coller dans les nouveaux scripts que vous écrivez

0
user5575

C'est ce que je prévois de faire pour un script qui se connecte à une base de données distante. Il nécessite 2 serveurs afin de stocker la clé séparément de la valeur chiffrée.

  1. Sur le serveur 2 (où la clé sera stockée), créez un script qui acceptera un paramètre de clé et le stockera localement.
  2. Sur le serveur 1 (où le script est stocké), créez un script qui acceptera la chaîne de connexion (hôte, nom_bd, nom d'utilisateur, mot de passe) comme paramètre et générera une clé aléatoire pour crypter la chaîne de connexion. Nous stockons la chaîne cryptée localement, hachons la clé et la stockons localement, puis envoyons la clé (via SSL) au serveur 2. Ce script devra être exécuté manuellement avec la chaîne de connexion réelle pour l'initialiser et peut être réexécuté vers réinitialiser la clé si le deuxième serveur est en quelque sorte compromis.
  3. Sur le serveur 1 Configurez le script d'origine pour accepter un paramètre de clé, validez la clé par rapport au hachage stocké, puis utilisez la clé pour déchiffrer la chaîne de connexion chiffrée.
  4. Sur le serveur 2 Configurez un appel cURL au script sur le serveur 1 (via SSL) qui envoie la clé et exécute le script. Cela peut être configuré sur cron ou comme vous le souhaitez.
0
knsheely