「引数をコマンドとして解釈するコマンドに、信頼できないデータを渡すコマンドを実行してください。」

「引数をコマンドとして解釈するコマンドに、信頼できないデータを渡すコマンドを実行してください。」

findutilsマニュアルから:

たとえば、これら2つのコマンドの構造は次のとおりです。

# risky
find -exec sh -c "something {}" \;
find -execdir sh -c "something {}" \;

非常に危険です。その理由は、「{}」がセミコロンやその他のシェル関連文字を含むことができるファイル名に拡張されるためです。たとえば、/tmp/foo; rm -rf $HOME上記の2つのコマンドは、誰かがファイルを作成した場合に誰かのホームディレクトリを削除できます。

そのため、信頼できないデータ(ファイル名など)をさらに解釈するために、引数を解釈するコマンドに渡すコマンド(例: "sh")を実行しないでください。

シェルの場合、この問題に対するきちんとした解決策があります。

# safer
find -exec sh -c 'something "$@"' sh {} \;
find -execdir sh -c 'something "$@"' sh {} \;

このアプローチはすべての問題を防ぐことを保証することはできませんが、攻撃者が選択したデータをシェルコマンドテキストに置き換えるよりもはるかに安全です。

  1. find -exec sh -c "something {}" \;代替項目が{}引用されず、単一の文字列として扱われないのが問題の原因ですか?
  2. ソリューションfind -exec sh -c 'something "$@"' sh {} \;では

    • が最初に{}置き換えられた{}が引用されていないので、"$@"元のコマンドと同じ問題がありますか?たとえば、これは、および?"$@"に拡張されます。"/tmp/foo;""rm""-rf""$HOME"

    • なぜ{}脱出または引用しないのですか?

  3. 同じ種類の問題と解決策(sh -c該当する場合は含めるかどうか、find必要ではない可能性があります)に適用され、最小限の例である他の例を提供できますか?注意を気を散らすことはできるだけ少ないのですか?バラより"bash -c"で実行されるコマンドに引数を与える方法

ありがとうございます。

ベストアンサー1

これは実際には参照には関係なく、パラメータ処理に関連しています。

危険な例を考えてみましょう。

find -exec sh -c "something {}" \;
  • これはシェルによって解析され、6つの単語に分けられます:、、、、、(findもはや引用符なし)、拡張する内容はありません。シェルは、この6つの単語を引数として使用して実行されます。-execsh-csomething {};find

  • findたとえば、処理する項目を見つけると、引数に置き換えられ、foo; rm -rf $HOME実行されます。{}foo; rm -rf $HOMEshsh-csomething foo; rm -rf $HOME

  • sh-cこれで結果が解析されたことがわかりますsomething foo; rm -rf $HOMEオプションではない最初のパラメータ)結果を実行します。

今、より安全なバリエーションを考えてみましょう。

find -exec sh -c 'something "$@"' sh {} \;
  • シェルは、、、、、、、、パラメータfindで実行されます。find-execsh-csomething "$@"sh{};

  • これfindが見つかったら、foo; rm -rf $HOME再び置き換えられ、{}パラメータ、、、で実行されます。shsh-csomething "$@"shfoo; rm -rf $HOME

  • sh-c、およびsomething "$@"を実行するコマンドで処理し、shおよびをfoo; rm -rf $HOME位置引数として処理します(から始まる$0)、"$@"次に拡張foo; rm -rf $HOME 単一値としてsomething単一の引数で実行しますfoo; rm -rf $HOME

を使用してこれを表示できますprintf。新しいディレクトリを作成し、入力して実行します。

touch "hello; echo pwned"

次のように最初のバリアントを実行します。

find -exec sh -c "printf \"Argument: %s\n\" {}" \;

生産する

Argument: .
Argument: ./hello
pwned

2番目のバリアントは次のように実行されます。

find -exec sh -c 'printf "Argument: %s\n" "$@"' sh {} \;

生産する

Argument: .
Argument: ./hello; echo pwned

おすすめ記事