Supposons que j'utilisais sha1pass
pour générer un hachage d'un mot de passe sensible sur la ligne de commande. Je peux utiliser sha1pass mysecret
pour générer un hachage de mysecret
mais cela a l'inconvénient qui mysecret
est maintenant dans l'histoire bash. Existe-t-il un moyen d’atteindre l’objectif final de cette commande tout en évitant de révéler mysecret
le texte brut, peut-être en utilisant une passwd
invite -style?
Je suis également intéressé par un moyen généralisé de faire cela pour transmettre des données sensibles à n'importe quelle commande. La méthode changerait lorsque les données sensibles seraient transmises sous forme d'argument (comme dans sha1pass
) ou sur STDIN à une commande.
Y a-t-il un moyen d'accomplir cela?
Edit : Cette question a attiré beaucoup d'attention et plusieurs bonnes réponses ont été proposées ci-dessous. Un résumé est:
- Selon la réponse de @ Kusalananda , idéalement, il ne serait jamais nécessaire de donner un mot de passe ou un secret en tant qu'argument de ligne de commande à un utilitaire. Ceci est vulnérable de plusieurs manières, comme décrit par lui, et on devrait utiliser un utilitaire mieux conçu capable de prendre l'entrée secrète sur STDIN.
- La réponse de @ vfbsilva explique comment éviter que des éléments ne soient stockés dans l'historique bash
- La réponse de @ Jonathan décrit une méthode parfaitement efficace pour accomplir cela tant que le programme peut prendre ses données secrètes sur STDIN. En tant que tel, j'ai décidé d'accepter cette réponse.
sha1pass
dans mon OP était juste un exemple, mais la discussion a établi qu'il existe de meilleurs outils qui prennent des données sur STDIN. - comme le note @R .. dans sa réponse , l'utilisation de l'extension de commande sur une variable n'est pas sans danger.
En résumé, j’ai accepté la réponse de @ Jonathan car c’est la meilleure solution étant donné que vous disposez d’un programme bien conçu et bien conçu. Bien que le fait de passer un mot de passe ou un secret en tant qu'argument de ligne de commande soit fondamentalement dangereux, les autres réponses permettent d'atténuer les simples problèmes de sécurité.
sha1pass mysecret
est en cours d'exécution et donc savoir ce qu'il enmysecret
est. (Cela ne fonctionne que pendant quelques secondes lorsque le programme est en cours d'exécution, bien sûr ...)Réponses:
Si vous utilisez le shell
zsh
oubash
, utilisez l'option -s duread
shell intégré pour lire une ligne à partir du terminal sans l'écho.Vous pouvez ensuite utiliser une redirection sophistiquée pour utiliser la variable en tant que stdin.
Si quelqu'un court
ps
, tout ce qu'il verra, c'est "sha1pass".Cela suppose que
sha1pass
le mot de passe de stdin (sur une ligne, en ignorant le séparateur de ligne) soit lu sans aucun argument.la source
sha1pass
n'utilise pas son flux d'entrée standard.sha1pass
était juste un exemple dans mon OP, et clairement pas le meilleur choix à utiliser pour cela.ps
, mais peut être écrit dans un fichier temporaire - si l'on veut éviter cela, alorssshpass < <(printf '%s\n' "$VARIABLE")
peut être considéré (parce queprintf
que commande externe, il n'est pas passé àexecv
et accessible viaps
).Idéalement, vous ne devez jamais taper un mot de passe en texte clair sur la ligne de commande en tant qu'argument d'une commande. Cela fait du mot de passe un argument de la commande et des arguments de ligne de commande peuvent être vus dans la table de processus en utilisant des outils simples tels que
ps
ou enregistrés dans certains journaux d'audit.Cela dit, il existe certainement des moyens de masquer le mot de passe actuel de l'historique des commandes du shell.
Tapez ensuite le mot de passe et appuyez sur Enter. La
head
commande utilisée ici accepte exactement une ligne d'entrée et la dernière nouvelle ligne que vous tapez ne fera pas partie des données transmisessha1pass
.Pour empêcher les caractères de faire écho:
La
stty -echo
commande désactive l'écho des caractères saisis sur le terminal. L'écho est alors restauré avecstty echo
.Pour transmettre l’entrée standard, cette dernière commande pourrait être modifiée (vous l’auriez fait si
sha1pass
les données acceptées sur l’entrée standard, mais comme si cet utilitaire ignorait son entrée standard):Si vous avez besoin d’une entrée multiligne (ce qui précède suppose qu’une seule ligne doit être passée, sans caractère de nouvelle ligne à la fin), remplacez la
head
commande entière parcat
et terminez l’entrée (en supposant que cesomecommand
soit lu jusqu’à la fin du fichier) par Ctrl+D( suivant Returnsi vous voulez inclure un caractère de nouvelle ligne dans l'entrée, ou deux fois sinon).Cela fonctionnerait quel que soit le shell que vous utilisiez (à condition qu'il s'agisse d'un shell de type Bourne ou de type rc).
Certains shells peuvent ne pas enregistrer les commandes saisies dans leurs fichiers d’historique si celle-ci est précédée d’un espace. Cela implique généralement de définir
HISTCONTROL
la valeurignorespace
. Ceci est soutenu par au moinsbash
etksh
sur OpenBSD, mais pas par exemple parksh93
oudash
.zsh
les utilisateurs peuvent utiliser l'histignorespace
option ou leurHISTORY_IGNORE
variable pour définir un modèle à ignorer.Dans les shells prenant en charge la lecture
read
sans écho des caractères sur le terminal, vous pouvez également utilisermais cela a évidemment toujours le même problème avec la possibilité de révéler le mot de passe dans la table de processus.
Si l'utilitaire lit à partir de l'entrée standard et si le shell prend en charge les "ici-chaînes", ce qui précède peut être remplacé par
Résumé des commentaires ci-dessous:
L'exécution d'une commande avec un mot de passe indiqué sur la ligne de commande, comme toutes les commandes ci-dessus, à l'exception de celle qui dirige les données vers la commande, rendra potentiellement le mot de passe visible pour tous ceux qui s'exécutent
ps
en même temps. Toutefois, aucune des commandes ci-dessus ne sauvegarde le mot de passe saisi dans le fichier d’historique du shell s’il est exécuté à partir d’un shell interactif.Les programmes bien conçus qui lisent les mots de passe en texte clair le font en lisant depuis leur entrée standard, depuis un fichier ou directement depuis le terminal.
sha1pass
do requiert le mot de passe sur la ligne de commande, que vous le saisissiez directement ou que vous utilisiez une forme de substitution de commande.Si possible, utilisez un autre outil.
la source
$(...)
fera partie de la ligne de commande et sera visible dans laps
sortie, sauf sur un système avec / proc durci.sha1pass
Exécuter sans mot de passe sur la ligne de commande semble produire une sortie sans rien lire ... Donc, OP doit choisir un outil différent.Si vous définissez
HISTCONTROL
comme ceci:et lancez la commande avec un espace:
il ne sera pas stocké dans l'historique.
la source
Passer des données sensibles via un tube ou here-doc:
ou:
Il est normal que des secrets se trouvent dans des variables shell (non exportées), mais vous ne pouvez jamais utiliser ces variables sur des lignes de commande, uniquement dans here-documents et les éléments internes du shell.
Comme l'a noté Kusalananda dans un commentaire, si vous entrez des commandes dans un shell interactif, les lignes que vous entrez pour un document here seront stockées dans l'historique du shell. Il est donc dangereux de taper un mot de passe ici utiliser des variables de shell contenant des secrets en toute sécurité; l'histoire contiendra le texte
$secret
plutôt que ce que$secret
développé.L'utilisation des extensions de commandes n'est pas sûre :
parce que la sortie sera incluse dans la ligne de commande et visible dans
ps
sortie (ou lue manuellement à partir de / proc) sauf sur les systèmes dotés de / proc durci.L'affectation à une variable est également acceptable:
la source
command_with_secret_output
qui me permet de taper la sortie secrète. Existe-t-il une telle commande qui pourrait être substituée ici?bash
session interactive enregistre le document dans l'historique.read
, par exempleread -r secret
. Ensuite, votre secret est dans$secret
. Vous pouvez exécuter stty avant / après pour masquer l'entrée si vous le souhaitez.sha1pass
semble fondamentalement cassé / inutilisable / dangereux car il ne peut pas lire le mot de passe de stdin ou d'un fichier. Je pense qu’il faut un utilitaire différent pour résoudre le problème.read -rs
fera le travail (si vous incluez-r
pour pouvoir avoir des mots de passe avec des barres obliques inverses), mais alors vous êtes de nouveau en train de montrer le mot de passe dans la liste de processus (et selon que la comptabilité de processus est activée et comment elle est configurée , dans les journaux de comptabilisation des processus également).Il suffit d'écrire la valeur dans un fichier et de le transmettre:
Je ne sais pas comment ça
sha1pass
marche, si vous pouvez utiliser un fichier en entrée, vous pouvez l'utilisersha1pass < mysecret
. Sinon, utilisercat
peut être un problème car il inclut la nouvelle ligne finale. Si c'est le cas, utilisez (si voshead
supports-c
):la source
cat | sha1pass
?cat mysecret | sha1pass
etsha1pass < mysecret
avoir le même comportement vis-à-vis des nouvelles lignes finales.cat
n'ajoute pas de nouvelles lignes. Quoi qu'il en soit, sisha1pass
supporte le passage du mot de passe via une entrée standard, je m'attendrais à ce qu'il ignore la nouvelle ligne finale par lui-même. Les fichiers avec des lignes qui ne sont pas terminées par des retours à la ligne ne sont pas naturels sous Unix, alors il serait difficile de s’attendre à ce qu’un fichier ne se termine pas par un retour à la ligne.cat | sha1pass
semble courirsha1pass
avant de me donner une chance d'entrer n'importe quelle entrée. ii) Non, bien sûr,cat mysecret
n'ajoute pas de nouvelle ligne, je n'ai jamais dit de l'cat
ajouter, seulement qu'elle l' inclue .< mysecret
enlève non plus. :)head -c-1
. Je suppose que je viens de me demander pourquoi utilisercat mysecret | sha1pass
et ensuite proposersha1pass < mysecret
. Je suppose que l'inquiétude est que sha1pass pourrait se plaindre de fichiers standard pour stdin; Je ne sais pas pourquoi.sha1pass
et n’ai trouvé aucun manuel ni-h
aucune autre forme de documentation au cours des quelques minutes que j’ai passées à chercher et que je ne pouvais donc pas savoir si son exécution étaitsha1pass foo
traitéefoo
comme une chaîne de saisie ou comme un fichier d’entrée . J'ai donc donné des options pour traiter chaque possibilité.Si ce que terdon a fait est possible, alors c'est la meilleure solution, en passant par l'entrée standard. Le seul problème est qu'il a écrit le mot de passe sur le disque. Nous pouvons le faire à la place:
Comme dit Kusalananda,
stty -echo
veille à ce que ce que vous tapez ne soit pas vu avant de lestty echo
refaire.head -1
obtiendra une ligne de l’entrée standard et la transmettra àsha1pass
.la source
j'utiliserais
cat
lirait de stdin jusqu’àEOF
, ce qui peut être provoqué en appuyant sur Ctrl + D. Ensuite, le résultat serait passé comme argument àsha1pass
la source