jidoka の動作をエミュレートして、Bashでのエラー処理を強化するために「サイレント」という名前のlibreプログラムを書いています。
私の質問は、次のように、呼び出し側のプログラムが入力を二重引用符で囲んでいる場合、そのevalがコードインジェクションに対して脆弱かどうかです。
silently "function" "command \"${@}\""
静かにこのコードを持っている:
#! /bin/bash
mainFunction () {
if [ "${function}" != "" ]; then
function="${function}: "
fi
error=$(eval "${command}" 2>&1)
if [ ${?} -ne 0 ]; then
echo "${function}${error}" >&2
exit "${exit}"
fi
}
setArguments () {
if [ "${1}" == "-try" ]; then
function="${2}"
command="${3}"
exit="0"
else
function="${1}"
command="${2}"
exit="1"
fi
}
setArguments "${@}"
mainFunction "${@}"
2つの簡単な観察があります。
eval
の使用は非常に危険であり、変数${command}
は効率的にサニタイズされていません。 (バッククォート、ピリオド、制御文字などを含めることができます)
bash
を使用して賢明な操作を行うことは、脆弱性が多いため推奨されません。重要なスクリプトには、貧弱なShell
(dash
など)を使用することをお勧めします。 (またはPythonまたはPerlのようなより進化した言語)。
予期しない動作の例:
/path/to/silently Blah "'echo `date`;return 1'"
Blah: Wed Oct 16 08:26:16 CEST 2019
backticksの間のコマンドが実行される場合、セミコロンはコマンドの分離を行い(通常どおり)、return 1
強制mainFunction
は、結果をエラーと見なして出力します。
@ gitlab.comで公開したコードを使用すると、この結果は次のようになります。
/path/to/silently Blah "'echo `date`;return 1'"
silently: surplus arguments on: Blah 'echo Thu Oct 17 13:54:36 CEST 2019;return 1'
Note that command must be quoted
date
コマンドが実行され、結果がエラーテキストとして表示されます。
それからあなたは試すことができます:
/path/to/silently Blah "'echo `cat /etc/passwd`;return 1'"
bash を使用して賢明な操作を行うことは可能ですが、強い経験が必要です。私は個人的にそれをしないことをお勧めします!
まず、ローカルシェルスクリプトへのコードインジェクションを心配する必要はありません。
これをリモートで実行している場合は、問題になる可能性があります。以下の例を試してみましたが、1つのWord以外の追加のコマンドを挿入する直接的な方法は見つかりませんでした。運用環境で許可されているコマンドもホワイトリストに登録する必要があることに注意してください。
例:サイレントに「コマンド\ "whoami \"」
#! /bin/bash
command="${@}"
result=$(eval "${command}" 2>&1)
echo "${result}"