0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】eval関数の使い方とリスク、第二引数・第三引数を活用した制限方法

Posted at

概要

文字列を式として認識してくれるeval関数を使ってみたので紹介します。

サンプルコード

eval関数は、文字列として渡されたPython式を評価し、その結果を返す関数。
以下公式ドキュメント。

以下、作成したサンプルコードです。

expression = "1 + 2 * 3"
eval_result = eval(expression)
print(f"Expression: {expression}, Eval_Result: {eval_result}")
# Expression: 1 + 2 * 3, Eval_Result: 7

上記の通り、Expressionの方では単なる文字列として出力されていますが、Eval_Resultでは文字列が式として評価されています。

ただし、こちら検索するとすぐに「脆弱性」「リスク」と言うワードが目に入ります。
と言うのも、計算式だけではなく、コマンドも実行できてしまうからです。

実際、悪意のあるコードが実行される可能性もあるため、使用する際は注意が必要です。

グローバル変数とローカル変数

上記のリスク回避のために、グローバル変数とローカル変数を指定することができます。
それぞれ、eval関数の第二、第三引数です。

以下、それらを追加したサンプルコード。

allowed_globals = {"__builtins__": None}
allowed_locals = {"x": 1, "y": 2, "z": 3}

expression = "x + y * z"
result = eval(expression, allowed_globals, allowed_locals)
print(f"Expression: {expression}, Result: {result}")

__builtins__Noneに設定することで、eval関数がデフォルトの組み込み関数にアクセスできないようになります。例えばos.removeなどでファイル削除するようなコマンドが実行できなくなります。

__builtins__とは...

builtinsモジュールを使えるグローバル変数です。
builtinsモジュールとは以下の通りで、組み込み関数へアクセスできます。

Python の全ての「組み込み」識別子に直接アクセスするためのもの
https://docs.python.org/ja/3/library/builtins.html

また、allowed_localsに「名前空間」を指定しそこで変数を設定したことで、特定のローカル変数のみの使用制限が実現できています。これで予期しない変数や関数へアクセスされることがなくなります。

上記で実行すると出力結果は以下のようになります。

Expression: x + y * z, Result: 7

ただし、上記Qiita記事はじめ、実運用に使う場合はリスクを払拭し切れるわけではないようですので、利用の際は他の方法も検討することをお勧めします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?