web-dev-qa-db-ja.com

「eval echo」を使用しても常に安全ですか?

evalを使用すると、任意のコードの実行が可能になるため、お勧めできません。ただし、eval echoの場合、残りの文字列はechoの引数になるため、安全である必要があります。これは正しいですか?

20
Cyker

反例:

DANGEROUS=">foo"
eval echo $DANGEROUS

echoへの任意の引数は、 "foo"と呼ばれるファイルを作成するよりも悪質なことをした可能性があります。

40
Celada

@Celadaは素晴らしい答えを提供してくれました。 evalが本当に悪であることを示すために、ここに"foo"というファイルを作成するよりも悪質なものを示します。

DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"

そしてもちろん"foo"と呼ばれるファイルを作成するよりも悪質なものよりも悪質なものが存在する可能性があります。

26
Cyker

いいえ、それはnotは常に安全です。 evalは任意のコマンドを実行できます。

次のような安全なコマンド(単一引用符内にあるため、日付は実行されません):

$ echo '$(date)'
$(date)

Evalと一緒に使用すると危険になります:

$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016

もちろん、日付はanyコマンドにすることもできます。

これを改善する1つの方法は、evalの引数をさらに引用することです。

$ eval echo '\$(date)'
$(date)

ただし、式を2回正しく引用することは通常困難です。

また、次のように外部の攻撃者が式を設定した場合、正しい引用を制御できなくなります。

$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!
12
Isaac

evalには常に注意が必要ですが、eval echo構築は必ずしも無意味であるとは限らず、canを安全に使用できます。最近、複数のブレース展開を必要な順序で評価するために必要でした。

bashは、左から右へ複数のブレース展開を行うので、

xargs -I_ cat _/{11..15}/{8..5}.jpg

に拡大する

xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg

しかし、私は最初に行われる2番目のブレースの拡張が必要でした。

xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg

それをするために私が思いつくことができた最高のものは

xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)

これは、単一引用符がevalコマンドラインの解析中に最初の中括弧のセットを展開から保護し、evalによって呼び出されたサブシェルによって展開されるため、機能します。

ネストされたブレース展開を含むいくつかの狡猾なスキームがあるかもしれませんが、これを1つのステップで行うことができます。 bash以外にも、この種のことを実現するための整然とした方法を可能にするシェルがあります。ただし、いずれの場合でも、evalの使用は安全です。その引数はすべて、パラメータ展開を含まない固定文字列だからです。

1
flabdablet