Szukam (1) najbezpieczniejszego i (2) najprostszego sposobu, aby użytkownik wpisał hasło w wierszu polecenia powłoki bash i aby hasło to stało się częścią standardowego programu.
Tak powinno wyglądać standardowe wejście:, {"username":"myname","password":"<my-password>"}
gdzie <my-password>
wpisane jest polecenie powłoki. Gdybym miał kontrolę nad programem stdin, mógłbym go zmodyfikować, aby bezpiecznie monitować o hasło i umieścić je na swoim miejscu, ale dalszy ciąg jest standardowym poleceniem ogólnego przeznaczenia.
Rozważyłem i odrzuciłem podejścia wykorzystujące:
- użytkownik wpisujący hasło w wierszu polecenia: hasło zostanie wyświetlone na ekranie, a także widoczne dla wszystkich użytkowników za pośrednictwem „ps”
- interpolacja zmiennej powłoki na argument do programu zewnętrznego (np.
...$PASSWORD...
): hasło byłoby nadal widoczne dla wszystkich użytkowników za pośrednictwem „ps” - zmienne środowiskowe (jeśli pozostaną w środowisku): hasło będzie widoczne dla wszystkich procesów potomnych; nawet wiarygodne procesy mogą ujawnić hasło, jeśli zrzucą podstawowe lub środowiskowe zmienne w ramach diagnostyki
- hasło przechowywane w pliku przez dłuższy czas, nawet plik z wąskimi uprawnieniami: użytkownik może przypadkowo ujawnić hasło, a użytkownik root może przypadkowo zobaczyć hasło
Podam moje obecne rozwiązanie jako odpowiedź poniżej, ale chętnie wybiorę lepszą odpowiedź, jeśli ktoś ją wymyśli. Myślę, że powinno być coś prostszego, a może ktoś zauważy obawy dotyczące bezpieczeństwa, za którymi tęskniłem.
Odpowiedzi:
Z
bash
lubzsh
:Bez
IFS=
,read
by rozebrać początkowe i końcowe spacje z hasłem podczas pisania.Bez
-r
tego przetwarzałby ukośniki odwrotne jako znak cytowania.Chcesz mieć pewność, że będziesz czytać tylko z terminala.
echo
nie można używać niezawodnie. Wbash
azsh
,printf
jest wbudowane tak, że wiersz polecenia nie pokaże na wyjściups
.W
bash
musisz zacytować,$password
ponieważ w przeciwnym razie zostanie zastosowany operator split + glob .To wciąż źle, ponieważ trzeba zakodować ten ciąg jako JSON. Na przykład problem polegałby na podwójnym cytowaniu i ukośniku odwrotnym. Prawdopodobnie musisz się martwić o kodowanie tych znaków. Czy twój program oczekuje ciągów UTF-8? Co wysyła twój terminal?
Aby dodać ciąg zachęty
zsh
:Z
bash
:źródło
unset password
iset +a
tam, choć można je pominąć, jeśli możesz przyjąć więcej założeń na temat bieżącej powłoki. Dobra uwaga na temat opcji -r do czytania i stawianiaIFS=
przed nią w celu uzyskania większej ogólności przy użyciu różnych haseł. Dobrze jest przejść z / dev / tty, aby wymusić wejście z terminala.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))'
, jeśli masz wokół siebie Pythona. W przypadku Python 2, s / input / raw_input /. Jeśli potokujesz hasło do tego polecenia, wypluje ono odpowiedni JSON.Oto rozwiązanie, które mam (zostało przetestowane):
Wyjaśnienie:
read -s
czyta linię standardowego (hasła) bez echa linii na ekranie. Przechowuje w zmiennej powłoki PASSWORD.echo -n $PASSWORD
umieszcza hasło na stdout bez nowej linii. (echo to wbudowane polecenie powłoki, więc nie jest tworzony nowy proces, więc (AFAIK) hasło jako argument do echa nie będzie pokazywane na ps.)$_
$_
do pełnego tekstu i wypisuje je na standardowe wyjścieJeśli chodzi o test POST HTTPS, druga linia będzie wyglądać tak:
źródło
printf '{"username":"myname","password":"%s"}' $PASSWORD
, co zachowuje te same właściwości bezpieczeństwa i oszczędza proces zewnętrzny.read
poleceń, które nie obsługują flagi -s, możesz użyć „stty -echo; przeczytaj HASŁO; stty echo”perl -e '...' <<< "$PASSWORD"
.<<<
wbash
przechowuje zawartość w tymczasowym pliku, który jest gorszy.Jeśli twoja wersja
read
nie obsługuje-s
, wypróbuj sposób zgodny z POSIX opisany w tej odpowiedzi .Ma
set +a
zapobiegać automatycznemu „eksportowaniu” zmiennej do środowiska. Powinieneś sprawdzić strony podręcznikastty
, ponieważ dostępnych jest wiele opcji.<<<"$passwd"
Jest cytowany z powodu dobrych hasła mogą mieć miejsca. Ostatnieecho
po włączeniustty echo
ma rozpocząć następną komendę / wyjście w nowym wierszu.źródło