2012-03-12 8 views
2

エンドユーザーは、返されたクエリが警告または警告(独自のしきい値に基づいて)をもたらすかどうかを評価するためのカスタムルールを持つことができるアプリケーションを構築することが任されています。Pythonでexec()を安全に使う方法は?

私はユーザーがロジックをテンプレート化する方法を作りました。

if (abs(<<21>>) >= abs(<<22>>)): 
    retVal = <<21>> 
else: 
    retVal = <<22>> 

<<21>><<22>>パラメータはプログラムで先に見つかった値に置換されます。例は次のようになります。すべてのこの置換は、変数(execCd)に保存されている。このように見えること、私は(この例では)非常に単純な場合/ elseブロックを持って発生したら:正しく

if (abs(22.0) >= abs(-162.0)): 
    retVal = 22.0 
else: 
    retVal = -162.0 

これますexec()。さて、これをどうすれば保護できますか?私はこの記事を見てきました:私はこの例外を有する第二と第三のパラメータを持っているとき

safe_list = ['math','acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'de grees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] 
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ]) 
safe_dict['abs'] = abs 
exec(execCd,{"__builtins__":None},safe_dict) 

しかし、幹部が失敗した - NameError: name 'retVal' is not defined

http://lybniz2.sourceforge.net/safeeval.html

私のコードは次のように見て終わりますエンドユーザーが持っているカスタムロジックの一部は、かなり頻繁であり、この変更の多くはかなり定期的に行われます。私はカスタムロジックを維持したくないので、エンドユーザはさまざまな警告/アラートのしきい値ロジックを素早くテストできるようにしたいと考えています。

安全でない(故意または意図しない)コードからこのexec文を保護するにはどうすればよいですか?

+2

ERR ... http://stackoverflow.com/questions/3688708/python-safe-sandbox(私は本当に、コピーして正確に貼り付けることができます) – geoffspear

答えて

4

execステートメントはローカル環境にretValを追加するのではなく、safe_dict辞書に追加します。だから、そこからそれを取り戻すことができます。

execCd = """ 
if (abs(22.0) >= abs(-162.0)): 
    retVal = 22.0 
else: 
    retVal = -162.0 
""" 

safe_list = ['math','acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'de grees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh'] 
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ]) 
safe_dict['abs'] = abs 
exec(execCd,{"__builtins__":None},safe_dict) 
retVal = safe_dict["retVal"] 
3

evalまたはexecを使用する唯一の安全な方法は、それらを使用しないことです。

execを使用する必要はありません。実行する文字列を作成するのではなく、オブジェクトを解析してコード実行を駆動します。

最も簡単には、関数をdictに格納し、文字列を使用して呼び出す関数を選択することができます。 Python構文を使用している場合、pythonはすべてのユーティリティを解析して使用する必要があります。

+0

することができますしてくださいあなたがここで話しているユーティリティを含める? – max

+1

@max 'ast'を検索 – Marcin

関連する問題