Je cherche le (1) moyen le plus sûr et (2) le plus simple pour qu'un utilisateur tape un mot de passe sur une invite shell bash et que ce mot de passe fasse partie de stdin dans un programme.
Voici à quoi doit ressembler le stdin:, {"username":"myname","password":"<my-password>"}
où <my-password>
est ce qui a été tapé dans l'invite du shell. Si j'avais le contrôle du programme stdin, je pourrais le modifier pour demander en toute sécurité un mot de passe et le mettre en place, mais l'aval est une commande standard à usage général.
J'ai considéré et rejeté les approches qui utilisent les éléments suivants:
- l'utilisateur tapant le mot de passe dans la ligne de commande: le mot de passe serait affiché à l'écran et serait également visible pour tous les utilisateurs via "ps"
- interpolation variable du shell dans un argument d'un programme externe (par exemple,
...$PASSWORD...
): le mot de passe serait toujours visible par tous les utilisateurs via "ps" - variables d'environnement (si elles sont laissées dans l'environnement): le mot de passe serait visible par tous les processus enfants; même les processus dignes de confiance peuvent exposer le mot de passe s'ils vident le noyau ou les variables d'environnement dans le cadre d'un diagnostic
- le mot de passe reste dans un fichier pendant une longue période, même un fichier avec des autorisations restreintes: l'utilisateur peut accidentellement exposer le mot de passe et l'utilisateur root peut accidentellement voir le mot de passe
Je mettrai ma solution actuelle comme réponse ci-dessous, mais je choisirai volontiers une meilleure réponse si quelqu'un en propose une. Je pense qu'il devrait y avoir quelque chose de plus simple ou peut-être que quelqu'un voit un problème de sécurité que j'ai manqué.
Réponses:
Avec
bash
ouzsh
:Sans
IFS=
,read
supprimerait les blancs de début et de fin du mot de passe que vous tapez.Sans
-r
, il traiterait les barres obliques inverses comme un caractère de citation.Vous voulez vous assurer de ne lire que depuis le terminal.
echo
ne peut pas être utilisé de manière fiable. Dansbash
etzsh
,printf
est intégré afin que la ligne de commande ne s'affiche pas dans la sortie deps
.Dans
bash
, vous devez citer$password
, sinon l' opérateur split + glob lui est appliqué.C'est toujours faux, car vous devez coder cette chaîne en JSON. Par exemple, les guillemets doubles et les contre-obliques au moins seraient un problème. Vous devez probablement vous soucier de l'encodage de ces caractères. Votre programme attend-il des chaînes UTF-8? Qu'envoie votre terminal?
Pour ajouter une chaîne d'invite, avec
zsh
:Avec
bash
:la source
unset password
etset +a
là, bien qu'il puisse être ignoré si vous pouvez faire plus d'hypothèses sur le shell actuel. Bon point sur l'option -r à lire et àIFS=
devancer pour une meilleure généralité avec une variété de mots de passe. Bon d'aller de / dev / tty pour forcer l'entrée du terminal.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))'
, si vous avez Python qui traîne. Pour Python 2, s / input / raw_input /. Si vous dirigez le mot de passe dans cette commande, il crachera le JSON approprié.Voici la solution que j'ai (elle a été testée):
Explication:
read -s
lit une ligne de stdin (le mot de passe) sans renvoyer la ligne à l'écran. Il stocke est dans la variable shell MOT DE PASSE.echo -n $PASSWORD
met le mot de passe sur stdout sans nouvelle ligne. (echo est une commande intégrée au shell, donc aucun nouveau processus n'est créé, donc (AFAIK) le mot de passe comme argument pour echo ne sera pas affiché sur ps.)$_
$_
dans le texte intégral et l'imprime sur stdoutSi cela va à un POST HTTPS, la deuxième ligne serait quelque chose comme:
la source
printf '{"username":"myname","password":"%s"}' $PASSWORD
, qui conserve les mêmes propriétés de sécurité et vous évite un processus externe.read
commandes qui ne prennent pas en charge l'indicateur -s, vous pouvez utiliser "stty -echo; read PASSWORD; stty echo"perl -e '...' <<< "$PASSWORD"
.<<<
enbash
stocke le contenu dans un fichier temporaire qui est pire.Si votre version de
read
ne prend pas en charge,-s
essayez la méthode compatible POSIX décrite dans cette réponse .Le
set +a
est censé empêcher l '"exportation" automatique d'une variable vers l'environnement. Vous devriez consulter les pages de manuel pourstty
, il y a beaucoup d'options disponibles. Le<<<"$passwd"
est cité parce que les bons mots de passe peuvent avoir des espaces. Le dernierecho
après avoir activé lestty echo
est de démarrer la prochaine commande / sortie sur une nouvelle ligne.la source