對於任何命令,有沒有辦法使用提示符在 bash 中傳遞敏感數據?
假設我
sha1pass
用來在命令行上生成一些敏感密碼的雜湊值。我可以用它sha1pass mysecret
來生成一個雜湊值,mysecret
但這具有mysecret
現在 bash 歷史中的缺點。有沒有辦法完成這個命令的最終目標,同時避免mysecret
以純文字形式顯示,也許是通過使用passwd
-style 提示?我也對將敏感數據傳遞給任何命令的通用方法感興趣。當敏感數據作為參數(例如 in
sha1pass
)或在 STDIN 上傳遞給某個命令時,該方法會發生變化。有沒有辦法做到這一點?
編輯:這個問題引起了很多關注,下面提供了幾個很好的答案。總結如下:
- 根據@Kusalananda 的回答,理想情況下,人們永遠不必將密碼或秘密作為命令行參數提供給實用程序。正如他所描述的,這在幾個方面很容易受到攻擊,應該使用設計更好的實用程序,該實用程序能夠在 STDIN 上獲取秘密輸入
- @vfbsilva 的回答描述瞭如何防止將事物儲存在 bash 歷史記錄中
- @Jonathan 的回答描述了一種非常好的方法來實現這一點,只要程序可以在 STDIN 上獲取其秘密數據。因此,我決定接受這個答案。
sha1pass
在我的 OP 中只是一個例子,但討論已經確定存在更好的工具來獲取 STDIN 上的數據。- 正如@R..在他的回答中指出的那樣,對變數使用命令擴展是不安全的。
因此,總而言之,我接受了@Jonathan 的回答,因為它是最好的解決方案,因為您有一個設計良好且表現良好的程序可以使用。儘管將密碼或機密作為命令行參數傳遞從根本上說是不安全的,但其他答案提供了減輕簡單安全問題的方法。
如果使用
zsh
orbash
shell,請使用內置 shell 的 -s 選項read
從終端設備讀取一行而不回顯它。IFS= read -rs VARIABLE < /dev/tty
然後你可以使用一些花哨的重定向來使用變數作為標準輸入。
sha1pass <<<"$VARIABLE"
如果有人跑
ps
,他們只會看到“sha1pass”。假設
sha1pass
在沒有給出任何參數的情況下從標準輸入讀取密碼(在一行上,忽略行分隔符)。
理想情況下,您永遠不要在命令行上鍵入明文密碼作為命令的參數。這樣做會使密碼成為命令的參數,並且可以通過使用簡單的工具(如
ps
或登錄到某些審計日誌)在程序表中看到命令行參數。話雖如此,肯定有一些方法可以從 shell 的命令歷史記錄中隱藏實際密碼。
sha1pass "$( head -n 1 )"
然後輸入密碼並按
Enter
。此處使用的head
命令只接受一行輸入,並且您鍵入的最後一個換行符不會是傳遞給的數據的一部分sha1pass
。為了防止字元回顯:
sha1pass "$( stty -echo; head -n 1; stty echo )"
該
stty -echo
命令關閉終端上鍵入字元的回顯。然後用 恢復迴聲stty echo
。要傳遞標準輸入,可以更改最後一個命令(如果
sha1pass
接受標準輸入上的數據,您會這樣做,但看起來好像這個特定實用程序忽略了它的標準輸入):{ stty -echo; head -n 1; stty echo; } | somecommand
head
如果您需要多行cat
輸入(上面假設應該傳遞單行,末尾沒有換行符),然後somecommand
用Ctrl+D
(如果您想在輸入中包含換行符,則跟隨Return
,否則兩次)。無論您使用什麼外殼(只要它是類似 Bourne 或類似 rc 的外殼),這都會起作用。
如果命令前面有空格,則某些shell 可能不會將鍵入的命令保存在其歷史文件中。這通常涉及必須設置
HISTCONTROL
為 valueignorespace
。至少OpenBSD 支持這一點,但不bash
支持,例如or 。使用者可以使用選項或他們的變數來定義要忽略的模式。ksh``ksh93``dash``zsh``histignorespace``HISTORY_IGNORE
在支持讀取
read
而不向終端回顯字元的 shell 中,您也可以使用IFS= read -rs password # -s turns off echoing in bash or zsh # -r for reading backslashes as-is, # IFS= to preserve leading and trailing blanks sha1pass "$password"
但這顯然仍然存在相同的問題,可能會洩露程序表中的密碼。
如果實用程序從標準輸入讀取,並且 shell 支持“here-strings”,則上面的內容可以更改為
IFS= read -rs password somecommand <<<"$password"
評論摘要如下:
- 使用在命令行上給出的密碼執行命令,上述所有命令都會執行此操作,除了將數據通過管道傳輸到命令的命令之外,可能會使同時執行的任何人都可以看到密碼
ps
。但是,如果從互動式 shell 執行,上述命令都不會將輸入的密碼保存在 shell 的歷史文件中。- 讀取明文密碼的行為良好的程序通過從其標準輸入、文件或直接從終端讀取來執行此操作。
sha1pass
確實需要命令行上的密碼,直接輸入或使用某種形式的命令替換。- 如果可能,請使用其他工具。