/usr/bin/env 作為一個 shebang - 及其安全意義

/usr/bin/env 作為一個 shebang - 及其安全意義

我在幾個地方看到了使用以下 shebang 行的建議

#!/usr/bin/env bash

代替

#!/usr/bin/bash

我下意識的反應是,“如果有人用這個可執行檔替換他們自己的可執行檔怎麼辦~/.local/bin?”此目錄通常設定在系統範圍路徑之前的使用者路徑中。我認為這是一個安全問題,通常作為旁注而不是任何值得認真對待的問題,但我想測試這個理論。

為了嘗試這個我做了這樣的事情:

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/bash
chmod 755 $HOME/.local/bin/bash
PATH=$HOME/.local/bin env bash

這產生

/usr/bin/env: ‘bash’: No such file or directory

為了檢查它是否拾取了任何東西,我也做了

echo -e "#!/usr/bin/python\nprint 'Hacked!'" > $HOME/.local/bin/perl
chmod 755 $HOME/.local/bin/perl
PATH=$HOME/.local/bin env perl

正如我所料,它會列印出

Hacked!

有人可以跟我解釋為什麼bash沒有找到替代品,但找到替代品了perl嗎?這是某種「安全」措施(從我的角度來看)沒有抓到重點嗎?

編輯:因為有人提示我:我不是問/usr/bin/env bash與使用有何不同/bin/bash。我正在問如上所述的問題。

EDIT2:這一定是我做錯了什麼。今天再次嘗試(使用顯式路徑env而不是隱式路徑),沒有出現這種「未找到」行為。

答案1

「如果有人用 ~/.local/bin 中的這個執行檔取代自己的執行檔怎麼辦?

那麼這個腳本對他們就不起作用了。

但這並不重要,因為他們可以透過其他方式自行破壞腳本,或者直接運行另一個程式而不會弄亂PATHenv

除非你的用戶有其他使用者的目錄PATH,或可以編輯PATH其他使用者的目錄,實際上不可能一個使用者弄亂另一個使用者。


但是,如果它不是 shell 腳本,而是授予額外權限的腳本,例如某些程式的 setuid 包裝器,那麼情況就會有所不同。在那種情況下,那就是必要的使用絕對路徑運行程序,請將其放置在非特權使用者無法修改的目錄中,並在啟動程序時清理環境。

答案2

至於 shell 和 之間的行為差異perlperl與 shell 檢查第一行以確定要執行的內容不同:

$ cat tcl
#!/usr/bin/env tclsh
puts "TCL running as [pid]"
$ perl tcl
TCL running as 39689
$ cat sbcl
#!/opt/local/bin/sbcl --script
(format t "~a running as ~a~%" 'lisp (sb-unix:unix-getpid))
$ perl sbcl
LISP running as 39766
$ 

此功能的用途包括用 Perl 以外的其他語言編寫測試因此,人們可以使用其他語言編寫與 TAP 相容的腳本,並且prove可以正確地執行它們。

答案3

這裡沒有安全風險。/usr/bin/env應該根據使用者的環境選擇合適的二進位。因此,如果使用者bash在 中安裝了自己的~/.local/bin版本,那麼/usr/bin/env確實應該嘗試使用它(例如,他們可能編譯了一個具有系統範圍版本中不可用的額外功能的版本,並且更願意在系統範圍版本的位置)。對於任何其他二進制/解釋器也是如此。不存在安全風險,因為用戶將無法運行任何他們本來無法運行的內容。

至於為什麼替代品在你的情況下失敗,我懷疑它與/usr/bin/env.嘗試運行PATH=~/.local/bin bashPATH=~/.local/bin bash <path-to-script>運行腳本時會呼叫它)並PATH=~/.local/bin /usr/bin/env bash查看哪些失敗。這應該可以提供有關“找不到文件”錯誤所指的線索。

相關內容