成語 ssh ... '$(typeset -f foo); foo'
有多安全?
假設
foo
在目前 shell 會話中定義了一些 shell 函式。然後命令typeset -f foo
列印出這個函式的原始碼。這意味著,至少在原則上,可以通過
ssh
如下所示在遠端主機上執行此功能:ssh <REMOTE-HOST> "$(typeset -f foo); foo"
(為了這個問題的目的,假設提到的所有命令和文件系統路徑在 . 中
foo
都可用<REMOTE-HOST>
。另外,假設它bash
是兩端的 shell。)我的直覺是,像這樣盲目地採購一些自動生成的原始碼會非常脆弱,但我還沒有想出
foo
這個成語失敗的函式範例。我的問題是:這個成語有多安全?如果它不安全,有人可以給我一個具體的例子來說明它是如何失敗的嗎?(安全問題包括以下內容:是否
bash
保證此類使用typeset -f
是安全的?)**注意:**在這篇文章中,我不是在尋找替代品。我只是想了解這個特殊成語的屬性。
編輯:澄清這
bash
是兩端的外殼。
如果程式碼未在與生成程式碼的語言環境相同的語言環境中解釋(或者如果語言環境名稱相同但該語言環境的定義在 ssh 客戶端主機和伺服器主機之間不同),則不安全。
blank
特別重要的是字元的編碼以及,alpha
和alnum
類別中字元的成員資格。例如,
α
BIG5 字元集中的字元(希臘字母小寫字母 alpha)被編碼為 0xa3 0x5c,0x5c 為\
ASCII(以及包括 BIG5 在內的所有字元集)。因此,如果您
foo
在該字元集中定義了一個函式:foo() { echo α }
typeset -f
將按原樣輸出,但如果在 C 等不同的語言環境中解釋,則 0xa3 0x5c 不會被視為 aα
,而是視為未知的 0xa3 字元,後跟反斜杠。可以像這樣利用:$ env LC_ALL=zh_TW.big5 $'BASH_FUNC_foo%%=() { echo \xa3\\\\;}; echo gotcha; }' bash -c 'typeset -f foo' | bash gotcha bash: line 5: syntax error near unexpected token `}' bash: line 5: `}'
在不同的語言環境中解釋時成為
foo() { echo α\;}; echo gotcha; }
。foo() { echo <0xa3>\\; }; echo gotcha; }
其他問題:
UTF-8 中的
à
字元編碼為 0xc3 0xa0。在 iso8859-1 和其他幾個iso8859
字元集中,0xa0 是不間斷空格字元。在某些系統上,該字元包含在空白字元類中,因此 bash 在其語法中將其視為標記分隔符。Solaris 就是這樣一個系統,其中 U+00A0 被視為空白:
$ env $'BASH_FUNC_foo%%=() { nawk -v x=àBEGIN\'{system("echo gotcha")}\' 1;}' bash -c 'typeset -f foo; echo foo' | ssh solaris LC_ALL=en_GB.ISO8859-1 bash gotcha
看看如何:
nawk -v x=àBEGIN... 1
被解釋為:
nawk -v x=<0xc3> 'BEGIN{system("...")}' 1
請注意,如果該函式是在 0xa0 不是空白或 0xa3 0x5c 是 alpha 的語言環境中定義的,
typeset -f
即使在它是空白的語言環境中呼叫它仍將輸出相同(解釋時產生不同的輸出)$ LC_ALL=zh_TW.big5 bash -c $'f() { echo \xa3\x5c$(uname); }; export LC_ALL=C; typeset -f f | bash' bash: line 3: syntax error near unexpected token `(' bash: line 3: ` echo �\$(uname)'
更一般地說,
typeset
,alias
,export -p
,set
,的輸出locale
都意味著適合重新輸入到 shell,但除了那些語言環境問題之外,已知各種實現都有幾個問題,如果還有很多問題,我不會感到驚訝更多的。所以,是的,我同意你認為它很危險是對的,最好只在你知道輸出數據來自哪裡的上下文中使用它們。例如,在 的情況下,僅在您定義的函式
typeset -f foo
上使用它(並避免在其中使用非 ASCII 字元)。foo