Saya mencari (1) cara paling aman dan (2) paling sederhana untuk meminta pengguna mengetikkan kata sandi di bash shell prompt dan menjadikan kata sandi itu menjadi bagian dari stdin ke suatu program.
Ini adalah apa yang perlu stdin terlihat seperti:, di {"username":"myname","password":"<my-password>"}
mana <my-password>
apa yang diketikkan ke prompt shell. Jika saya memiliki kendali atas program stdin, maka saya bisa memodifikasinya untuk secara aman meminta kata sandi dan meletakkannya, tetapi downstream adalah perintah tujuan umum standar.
Saya telah mempertimbangkan dan menolak pendekatan yang menggunakan yang berikut:
- pengguna mengetik kata sandi ke dalam baris perintah: kata sandi akan ditampilkan di layar dan juga akan terlihat oleh semua pengguna melalui "ps"
- interpolasi variabel shell menjadi argumen ke program eksternal (misalnya,
...$PASSWORD...
): kata sandi masih akan terlihat oleh semua pengguna melalui "ps" - variabel lingkungan (jika dibiarkan di lingkungan): kata sandi akan terlihat oleh semua proses anak; bahkan proses yang dapat dipercaya dapat mengekspos kata sandi jika mereka membuang inti atau membuang variabel lingkungan sebagai bagian dari diagnostik
- kata sandi yang tersimpan dalam file untuk waktu yang lama, bahkan file dengan izin ketat: pengguna dapat secara tidak sengaja mengekspos kata sandi dan pengguna root mungkin secara tidak sengaja melihat kata sandi
Saya akan meletakkan solusi saya saat ini sebagai jawaban di bawah, tetapi dengan senang hati akan memilih jawaban yang lebih baik jika seseorang datang dengan satu. Saya pikir harus ada sesuatu yang lebih sederhana atau mungkin seseorang melihat masalah keamanan yang saya lewatkan.
Jawaban:
Dengan
bash
atauzsh
:Tanpa
IFS=
,read
akan menghapus blanko terkemuka dan tertinggal dari kata sandi yang Anda ketikkan.Tanpa
-r
, itu akan memproses garis miring terbalik sebagai karakter mengutip.Anda ingin memastikan bahwa Anda hanya pernah membaca dari terminal.
echo
tidak bisa digunakan dengan andal. Dibash
danzsh
,printf
dibangun sehingga baris perintah tidak akan ditampilkan di outputps
.Di
bash
, Anda perlu mengutip$password
karena jika tidak operator split + glob diterapkan padanya.Itu masih salah karena Anda harus menyandikan string itu sebagai JSON. Sebagai contoh, double-quote dan backslash setidaknya akan menjadi masalah. Anda mungkin perlu khawatir tentang pengkodean karakter tersebut. Apakah program Anda mengharapkan string UTF-8? Apa yang dikirim terminal Anda?
Untuk menambahkan string prompt, dengan
zsh
:Dengan
bash
:sumber
unset password
dan diset +a
sana, meskipun itu dapat dilewati jika Anda dapat membuat lebih banyak asumsi tentang shell saat ini. Poin bagus tentang opsi -r untuk membaca dan mengedepankannyaIFS=
untuk generalisasi yang lebih baik dengan beragam kata sandi. Baik untuk beralih dari / dev / tty untuk memaksa input dari terminal.python3 -c 'import json; print(json.dumps({"username": "myname", "password": input()}))'
, Jika Anda memiliki Python di sekitar. Untuk Python 2, s / input / raw_input /. Jika Anda memasukkan kata sandi ke perintah itu, itu akan memuntahkan JSON yang sesuai.Inilah solusi yang saya miliki (sudah diuji):
Penjelasan:
read -s
membaca garis stdin (kata sandi) tanpa menggema garis ke layar. Ini menyimpan dalam variabel PASSWORD shell.echo -n $PASSWORD
menempatkan kata sandi di stdout tanpa baris baru. (Gema adalah perintah bawaan shell sehingga tidak ada proses baru yang dibuat sehingga (AFAIK) kata sandi sebagai argumen untuk gema tidak akan ditampilkan pada ps.)$_
$_
ke dalam teks lengkap dan mencetaknya ke stdoutJika ini menuju HTTPS POST, baris kedua akan menjadi seperti:
sumber
printf '{"username":"myname","password":"%s"}' $PASSWORD
, yang mempertahankan properti keamanan yang sama dan menghemat proses eksternal.read
perintah yang tidak mendukung flag -s, Anda dapat menggunakan "stty -echo; baca PASSWORD; stty echo"perl -e '...' <<< "$PASSWORD"
.<<<
dalambash
menyimpan konten dalam file sementara yang lebih buruk.Jika versi
read
Anda tidak mendukung,-s
Anda mencoba cara yang kompatibel POSIX yang terlihat dalam jawaban ini .The
set +a
seharusnya untuk mencegah auto "ekspor" dari variabel lingkungan. Anda harus memeriksa halaman manual untukstty
, ada banyak opsi yang tersedia. Itu<<<"$passwd"
dikutip karena kata sandi yang baik dapat memiliki ruang. Yang terakhirecho
setelah mengaktifkanstty echo
adalah untuk memiliki perintah / output berikutnya mulai pada baris baru.sumber