Bash

成語 ssh ... '$(typeset -f foo); foo' 有多安全?

  • January 11, 2018

假設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特別重要的是字元的編碼以及,alphaalnum類別中字元的成員資格。

例如,α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

引用自:https://unix.stackexchange.com/questions/416209