web-dev-qa-db-ja.com

Python:evalを安全にする

Pythonで「電卓API」を実行する簡単な方法が欲しい。

現時点では、電卓がサポートする機能の正確なセットについてはあまり気にしていません。

文字列を受け取りたい、たとえば"1+1"を返し、結果を文字列で返します。この場合は"2"

そのようなことに対してevalを安全にする方法はありますか?

まず始めに

env = {}
env["locals"]   = None
env["globals"]  = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None

eval(users_str, env)

これにより、呼び出し元がローカル変数を変更する(または参照する)ことができなくなります。

しかし、私はここで多くを監督していると確信しています。

evalのセキュリティ問題は修正可能ですか、それとも正常に機能させるには細かすぎる細部がありますか?

40
flybywire

evalのセキュリティ問題は修正可能ですか、それとも正しく機能させるには細かすぎる細部がありますか?

間違いなく後者-巧妙なハッカーは常にあなたの予防策を回避する方法を見つけることができます。

基本タイプのリテラルのみを使用する単純な表現で満足している場合は、 ast.literal_eval を使用してください-それが目的です!何よりもおもしろい場合は、クラシックなlexx/yaccアプローチに慣れていて快適な場合は ply のような解析パッケージを推奨します。Pythonicアプローチの可能性がある場合は pyparsing を推奨します。 。

58
Alex Martelli

プロセスで定義されたanyクラスへのアクセスを取得することが可能で、それをインスタンス化してメソッドを呼び出すことができます。 CPythonインタープリターをセグメント化するか、終了させることができます。これを見てください: 評価は本当に危険です

12
Ned Batchelder

セキュリティ問題は修正可能ではありません(それに近いものでも)。

私は pyparsing を使用して式をトークンのリストに解析し(文法は簡単なので、これは難しくありません)、トークンを個別に処理します。

ast モジュールを使用してPython ASTを構築することもできます(有効なPython構文を使用しているため) )、しかしこれは微妙なセキュリティホールに開かれているかもしれません。

1
Katriel

PerlにはSafe evalモジュールがあります http://perldoc.Perl.org/Safe.html

「PythonでのPerl Safeに相当するもの」をグーグル検索すると http://docs.python.org/2/library/rexec.html が見つかります

しかし、このPython "restricted exec"は非推奨です。

-

全体として、あらゆる言語での「評価」セキュリティは大きな問題です。 SQLインジェクション攻撃は、このようなセキュリティホールのほんの一例です。 Perl Safeには何年にもわたってセキュリティバグがありました-最近覚えているのは、safe evalから返されたオブジェクトのデストラクタを除いて、安全でした。

それは私が自分のツールに使用するかもしれない種類のものですが、Web公開されていません。

ただし、いつか完全に安全なevalが多くの言語で利用可能になることを願っています。

1
Krazy Glew