2012-02-04 7 views
4

制限付きエバールの実行に関する良い情報があるかどうか不思議です。Perl:安全な評価?

ドキュメントを見ると、revalメソッドを持つuse Safeがありますが、どの程度安全かはわかりません。

私がしたいことは、さまざまな条件文を、evalを悪用したソースのない関数に文字列として渡すことができるようにすることです。例えば

sub foo { 
    my $stmt = shift; 
    my $a = 3; 
    say eval($stmt)?"correct":"wrong") , "($stmt)"; 
} 

foo(q{1 == $a}); 
foo(q{$a =~ /3/); 
foo(q{(sub {return 3})->() eq 3} ); 

use Safeこのために良いでしょうか?私ができる必要があるのは、比較、ディスクアクセス、または可変操作です。

答えて

4

indicated in the docsの場合、eval($stmt)は現在のPerlプログラムの語彙コンテキストで$stmt "と評価されます。そのため、後で変数設定やサブルーチンと書式定義が残ります。これは実行時まで$stmtの実行を遅らせるのに便利です。

あなたSafeコンパートメント内reval($stmt)、同じことが起こる、本質的に、文がeval'dされていますが、それは唯一の安全なコンパートメントの名前空間を参照することができ、新たな語彙的文脈でeval'dだし、ここであなたがコントロールすることができる場合どんな種類の演算子が許可されていますか?

セーフコンパートメントとそのコンパートメントにreval($stmt)を指定すると、(a)$stmtを実行しても、あなたの同意なしにプログラムの機能が変更されることはありません(これは "w/o evalを悪用するソース ")。そして、(b)はい、あなたがreval($stmt)なら、あなたの同意なしに$stmtはディスクにアクセスすることができません。 (a)「あなたの同意」ではシンボルテーブルを明示的に使用する必要があり、(b)「同意する」ではディスクアクセスを許可するop codesのセットを指定する必要があります。

これはどれだけ安全かわかりません。しかし、それを設定してデバッガでステップ実行すると、実際に動作していることがわかります。

+0

Jason、thx。私が「評価を濫用する」という意味は、何かを破壊するためのコードを注入することです。 Evalは注意して処理する必要がありますが、この場合は使用するモジュールを作成していますので、より安全にするために何ができるかは参考になります。私はcodepad.orgが何らかの形の子牛を使用していると信じなければならず、あなたが 'print \' ls -l \ ';を試してみると、' 'システムコールを受け付けない:SYS_pipe' – vol7ron

+0

、これはまさにrevalがあなたにできる。基本的にミニプログラミング環境を備えたアプリケーションで使用します。また、configファイルにはperlのデータ構造が直接含まれているので、configファイルに環境を変更させる前にそこに行くのが面白いとは限りません。 – Jason

+0

ありがとうございましたJason、匿名サブルーチンコール(私の最後の例)がまだ実行できるかどうか知っていますか? – vol7ron