GNU/Linux >> Linux の 問題 >  >> Linux

イディオムの安全性`ssh…“ $(typeset -f Foo);フー」`?

いくつかのシェル関数foo 現在のシェルセッションで定義されています。次に、コマンド

typeset -f foo

この関数のソースコードを出力します。これは、少なくとも原則として、sshを介してリモートホストでこの機能を実行できることを意味します。 以下に示すように:

ssh <REMOTE-HOST> "$(typeset -f foo); foo"

(この質問の目的のために、fooによって言及されたすべてのコマンドとファイルシステムパスを想定します <REMOTE-HOST>で利用可能です 。また、bash 両端のシェルです。)

私の本能は、このような自動生成されたソースコードを盲目的に調達することは非常に脆弱であるということですが、関数fooの例を思い付くことができませんでした。 このイディオムが失敗する場所。

私の質問は:このイディオムはどれくらい安全ですか?安全でない場合、誰かがそれがどのように失敗するかを説明する具体的な例を教えてもらえますか? (安全性の問題には次のものが含まれます:bash typeset -fのそのような使用を保証します 安全ですか?)

NB: この投稿では、私は代替案を探していません。この特定のイディオムの特性を理解したいだけです。

編集:bash 両端のシェルです。

承認された回答:

コードが生成されたロケールと同じロケールで解釈されない場合(またはロケール name の場合)は安全ではありません。 は同じですが、そのロケールの定義はsshクライアントホストとサーバーホストで異なります。

特に重要なのは、blank内の文字のエンコードと文字のメンバーシップです。 、alpha およびalnum カテゴリ。

たとえば、α BIG5文字セットの文字(ギリシャ文字の小文字のアルファ)は0xa3 0x5cとしてエンコードされ、0x5cはです。 ASCII(およびBIG5を含むすべての文字セット)。

したがって、fooがある場合 その文字セットで次のように定義された関数:

foo() {
  echo α
}

typeset -f はそのように出力しますが、Cのような別のロケールで解釈された場合、その0xa30x5cはαとは見なされません。 ただし、不明な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の文字は、0xc30xa0としてエンコードされます。 iso8859-1および他のいくつかのiso8859 文字セット、0xa0はノーブレークスペース文字です。一部のシステムでは、その文字は空白に含まれています 文字クラス。構文のトークン区切り文字としてbashによって尊重されます。

関連:Linux –ファイルパーミッションは実行のみですか?

Solarisは、U + 00A0が空白と見なされるそのようなシステムの1つです:

$ 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がアルファであるロケールで関数が定義されている場合は、typeset -f 空白のロケールで呼び出された場合でも、同じように出力されます(解釈すると異なる出力が生成されます)

$ LC_ALL=zh_TW.big5 bash -c $'f() { echo xa3x5c$(uname); }; export LC_ALL=C; typeset -f f | bash'
bash: line 3: syntax error near unexpected token `('
bash: line 3: `    echo �$(uname)'

より一般的には、typesetの出力 、aliasexport -psetlocale すべて意味がある シェルへの再入力に適していますが、これらのロケールの問題に加えて、さまざまな実装にいくつかの問題があることが知られており、さらに多くの問題があったとしても驚かないでしょう。

ですから、そうです、あなたはそれを危険だと考えるのは正しいと思います。出力されるデータがどこから来ているのかがわかっている状況でのみ使用することをお勧めします。たとえば、typeset -f fooの場合 、fooでのみ使用してください あなたの機能 定義済み(および非ASCII文字の使用は避けてください)。


Linux
  1. Bash スクリプトのスクリプト ファイル名を知るにはどうすればよいですか?

  2. 前の bash コマンドの引数を思い出すにはどうすればよいですか?

  3. bash プロンプトにアイコンを追加する方法

  1. bashでファイルの絶対ディレクトリを取得するにはどうすればよいですか?

  2. bashで文字列内の単語のインデックスを見つける方法は?

  3. Debian VM の Bash の解像度を変更するにはどうすればよいですか?

  1. .bashrcの目的とそれはどのように機能しますか?

  2. ターミナルでループバッシュスクリプトを停止する方法は?

  3. Rsync〜/ foo Target / fooはRsync〜/ foo / Target / foo /と同じですか?