「eval echo」を使用するのは常に安全ですか?


20

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


1
必ずしも安全ではないため、フォークボムまたは厄介なrm -fR *をラップできます。
μολὼν.λαβέ16年

たぶんこれは単なる思考実験ですが、実際にこれを実行して複数の引数を渡すことを考えている場合は、-n引用符で囲まれていない変数echo $argumentsまたはif $argumentsが配列の場合に行うことができますecho "${arguments[@]}"。安全eval echoあっても、使用することは無意味です。
JOL

回答:


40

反例:

DANGEROUS=">foo"
eval echo $DANGEROUS

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


6
また、:のDANGEROUS="hello;ls"代わりの任意のコマンドの場合ls
クサラナンダ

2
また:(DANGEROUS='$(ls)'さらにエスケープが必要な場合があります)。
wizzwizz4 16

だろうeval echo '"'"$DANGEROUS"'"'動作しますか?これは、上には思わgoo.gl/L2pPQP
イスマエルミゲル

@IsmaelMiguel wizzwizz、Cyker、またはsorontarの例、または文字列に二重引用符が含まれているもの(egなどDANGEROUS='">foo"')では機能しません。
ゴードンデイヴィソン

くそー 私は少しを助けた何かを見つけIかかわらず
イスマエルミゲル

26

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

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

そしてもちろん、 "foo"と呼ばれるファイルを作成するよりも邪悪なものよりももっと邪悪なものがあります


8
+1のよう"$THIS"に変数を引用するだけではなく、変数を引用するだけ$THISでも役に立ちません!
セラダ

引用符の追加ペアを送信すると役立つようです。のようなものeval echo '"'"$DANGEROUS"'"'goo.gl/L2pPQPで
イスマエルミゲル

実際、あなたの例は>foo、「foo」という名前のファイルを作成することだけでなくてもよいため、これ以上悪意のあるものではありません>foo。あなたの例の唯一の本当の違いは、空のファイルを残さないということです。内容はまだありません。
flarn2006

12

いいえ、常に安全とは限りません。evalは任意のコマンドを実行できます。

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

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

evalと併用すると危険になります:

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

もちろん、日付はどのコマンドでもかまいません

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

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

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

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

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

1

それがあることは事実ですがeval、常に慎重に近づいする必要があり、eval echo建設は常に無意味ではないとすることができ、安全に使用すること。最近、複数のブレース展開を必要な順序で評価するために必要でした。

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です。

ネストされたブレース展開を含むいくつかのunningなスキームがあり、これが1つのステップで発生する可能性がありますが、ある場合、私はそれを見るには古すぎて愚かです。それ以外にもbash、この種のことを達成するための整然とした方法を可能にするシェルがあります。ただし、いずれの場合でも、eval引数はパラメータ展開を含まない固定文字列であるため、この使用は安全です。


ここでエコーとコマンド置換を行う必要はありません(これも$ IFSに依存しています)。できることeval xargs -I_ cat _/'{11..15}'/{8..5}.jpg
ステファンシャゼラス

これも機能しますが、xargsプロセスが終了するまで、evalによって生成されたサブシェルプロセスが動き続けます。eval echoバージョンは、xargsが開始される前にそのサブシェルを消滅させます。これはおそらく、htopツリービューに表示され、-xログを設定するものについて私と同じくらい他の人にとってのみ重要です:
flabdablet
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.