env USER=..some code... ./script.sh
スクリプト自体が使用するecho $USER
か、設定を介していくつかの実行可能なシェルコードを渡すことができることを考えるとtmpdir=/var/tmp/log-$USER
答え1
環境変数のシェルコードを問題なくスクリプトに渡すことができますが、スクリプトは変数のシェルコードを予想し、次のように評価する必要があります。
例えば
$ env USER='$(echo hello)' bash -c 'echo "$USER"'
$(echo hello)
そして
$ env USER='$(echo hello)' bash -c 'eval "echo \"$USER\""'
hello
上記の両方のコマンドでは、コードスニペットが$USER
スクリプトに渡されますbash -c
。コードは、評価された場合に文字列を出力する単純なコマンド置換であり、hello
シェルを呼び出すといいえコマンド置換は一重引用符内の文字列なので評価されます。最初のbash -c
スクリプトは文字列を評価しないため、シェルコードを印刷します。 2番目のbash -c
スクリプトは、渡された文字列を呼び出しの一部として評価してecho
印刷しますecho
(デフォルトでは)echo "$(echo hello)"
。
この問題に対する解決策は、ユーザーが任意のシェルコードをスクリプトに渡す可能性があるため、脆弱で危険です。依存するコードをパスして無条件に実行してください。)これは典型的なコード注入の脆弱性です。
私の考えでは、あなたがしたいことは合格だと思います。ひも、シェルコードではありません:
$ env USER="$(echo hello)" bash -c 'echo "$USER"'
hello
ここで、変数はスクリプトを呼び出す前に文字列に設定されますUSER
(シェルが二重引用符内でコマンド置換を拡張するため)。その後、スクリプトはその文字列を取得してエコーします。あなたの場合、スクリプトはその文字列を取得し、パス名の一部として使用します。hello
bash -c
重要なのは、スクリプトが文字列を取得する前にユーザーが文字列を計算することです。