Ich suche nach der (1) sichersten und (2) einfachsten Möglichkeit, einen Benutzer ein Kennwort an einer Bash-Shell-Eingabeaufforderung eingeben zu lassen und dieses Kennwort Teil von stdin für ein Programm zu machen.
So muss das stdin aussehen: {"username":"myname","password":"<my-password>"}
Wo <my-password>
ist, was in die Shell-Eingabeaufforderung eingegeben wurde? Wenn ich die Kontrolle über das Programm stdin hätte, könnte ich es so ändern, dass ich sicher nach einem Passwort frage und es einrichte, aber der Downstream ist ein Standardbefehl für allgemeine Zwecke.
Ich habe Ansätze in Betracht gezogen und abgelehnt, die Folgendes verwenden:
- Der Benutzer gibt das Passwort in die Befehlszeile ein: Das Passwort wird auf dem Bildschirm angezeigt und ist auch für alle Benutzer über "ps" sichtbar.
- Shell-Variableninterpolation in ein Argument für ein externes Programm (z. B.
...$PASSWORD...
): Das Passwort wäre weiterhin für alle Benutzer über "ps" sichtbar. - Umgebungsvariablen (wenn sie in der Umgebung verbleiben): Das Kennwort ist für alle untergeordneten Prozesse sichtbar. Selbst vertrauenswürdige Prozesse können das Kennwort offenlegen, wenn sie im Rahmen einer Diagnose Kern- oder Umgebungsvariablen sichern
- Das Kennwort befindet sich über einen längeren Zeitraum in einer Datei, auch in einer Datei mit eingeschränkten Berechtigungen: Der Benutzer kann das Kennwort versehentlich offenlegen und der Root-Benutzer kann das Kennwort versehentlich sehen
Ich werde meine aktuelle Lösung als Antwort unten angeben, aber gerne eine bessere Antwort auswählen, wenn jemand eine findet. Ich denke, es sollte etwas Einfacheres geben, oder vielleicht sieht jemand ein Sicherheitsrisiko, das ich übersehen habe.
Antworten:
Mit
bash
oderzsh
:Ohne
IFS=
,read
würde Streifen führende und nachgestellte Leerzeichen aus dem Passwort , das Sie eingeben.Ohne
-r
würde es Backslashes als Anführungszeichen verarbeiten.Sie möchten sicherstellen, dass Sie immer nur vom Terminal lesen.
echo
kann nicht zuverlässig verwendet werden. Inbash
undzsh
,printf
ist builtin , so dass Befehlszeile in der Ausgabe von nicht zeigen würdeps
.In
bash
müssen Sie zitieren,$password
da sonst der Operator split + glob darauf angewendet wird.Das ist jedoch immer noch falsch, da Sie diese Zeichenfolge als JSON codieren müssten. Zum Beispiel wären zumindest doppelte Anführungszeichen und Backslash ein Problem. Sie müssen sich wahrscheinlich um die Codierung dieser Zeichen kümmern. Erwartet Ihr Programm UTF-8-Zeichenfolgen? Was sendet Ihr Terminal?
So fügen Sie eine Eingabeaufforderungszeichenfolge hinzu
zsh
:Mit
bash
:quelle
unset password
undset +a
dort haben, obwohl es übersprungen werden kann, wenn Sie mehr Annahmen über die aktuelle Shell machen können. Guter Punkt über die Option -r zum Lesen und VoranstellenIFS=
für eine bessere Allgemeinheit mit einer Vielzahl von Passwörtern. Gut, um von / dev / tty zu gehen und die Eingabe vom Terminal zu erzwingen.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))'
, wenn Sie Python herumliegen haben. Für Python 2 s / input / raw_input /. Wenn Sie das Kennwort in diesen Befehl einfügen, wird der entsprechende JSON ausgespuckt.Hier ist die Lösung, die ich habe (sie wurde getestet):
Erläuterung:
read -s
liest eine Zeile von stdin (das Passwort), ohne die Zeile auf dem Bildschirm wiederzugeben. Es speichert ist in der Shell-Variablen PASSWORD.echo -n $PASSWORD
setzt das Passwort ohne Zeilenumbruch auf stdout. (echo ist ein in die Shell integrierter Befehl, daher wird kein neuer Prozess erstellt, sodass (AFAIK) das Kennwort als Argument für echo auf ps nicht angezeigt wird.)$_
$_
in den Volltext ein und druckt es auf stdoutWenn dies zu einem HTTPS-POST geht, wäre die zweite Zeile ungefähr so:
quelle
printf '{"username":"myname","password":"%s"}' $PASSWORD
, das die gleichen Sicherheitseigenschaften beibehält und Ihnen einen externen Prozess erspart.read
Befehle verallgemeinern möchten, die das Flag -s nicht unterstützen, können Sie "stty -echo; PASSWORT lesen; stty echo" verwendenperl -e '...' <<< "$PASSWORD"
.<<<
inbash
speichert den Inhalt in einer temporären Datei , die schlimmer ist.Wenn Ihre Version von
read
nicht unterstützt-s
, versuchen Sie es mit der in dieser Antwort gezeigten POSIX-kompatiblen Methode .Das
set +a
soll den automatischen "Export" einer Variablen in die Umgebung verhindern. Sie sollten in den Manpages nachsehen, obstty
viele Optionen verfügbar sind. Das<<<"$passwd"
wird zitiert, weil gute Passwörter Leerzeichen haben können. Das letzteecho
nach dem Aktivieren vonstty echo
ist, dass der nächste Befehl / die nächste Ausgabe in einer neuen Zeile beginnt.quelle