Sandbox —Jinjaドキュメント

提供:Dev Guides
Jinja/docs/3.0.x/sandbox
移動先:案内検索

サンドボックス

Jinjaサンドボックスは、信頼できないコードを評価するために使用できます。 安全でない属性やメソッドへのアクセスは禁止されています。

env がデフォルト構成のSandboxedEnvironmentであると仮定すると、次のコードはそれがどのように機能するかを示しています。

>>> env.from_string("{{ func.func_code }}").render(func=lambda:None)
u''
>>> env.from_string("{{ func.func_code.do_something }}").render(func=lambda:None)
Traceback (most recent call last):
  ...
SecurityError: access to attribute 'func_code' of 'function' object is unsafe.

API

class jinja2.sandbox.SandboxedEnvironment([options])

サンドボックス環境。 通常の環境と同じように機能しますが、サンドボックス化されたコードを生成するようコンパイラーに指示します。 さらに、この環境のサブクラスは、どの属性または関数に安全にアクセスできるかをランタイムに通知するメソッドをオーバーライドする場合があります。

テンプレートが安全でないコードにアクセスしようとすると、 SecurityError が発生します。 ただし、レンダリング中に他の例外も発生する可能性があるため、呼び出し元はすべての例外がキャッチされていることを確認する必要があります。

パラメーター
  • argsAny )–

  • kwargsAny )–

リターンタイプ

なし

call_binop(context, operator, left, right)

インターセプトされた二項演算子呼び出し( Intercepted_binops())の場合、組み込み演算子の代わりにこの関数が実行されます。 これは、特定の演算子の動作を微調整するために使用できます。

バージョン2.6の新機能。

パラメーター
リターンタイプ

どれでも

call_unop(context, operator, arg)

インターセプトされた単項演算子呼び出し( Intercepted_unops())の場合、組み込み演算子の代わりにこの関数が実行されます。 これは、特定の演算子の動作を微調整するために使用できます。

バージョン2.6の新機能。

パラメーター
リターンタイプ

どれでも

default_binop_table: Dict[str, Callable[[Any, Any], Any]] = {'%': <built-in function mod>, '*': <built-in function mul>, '**': <built-in function pow>, '+': <built-in function add>, '-': <built-in function sub>, '/': <built-in function truediv>, '//': <built-in function floordiv>}

二項演算子のデフォルトのコールバックテーブル。 このコピーは、サンドボックス環境の各インスタンスでbinop_tableとして入手できます。

default_unop_table: Dict[str, Callable[[Any], Any]] = {'+': <built-in function pos>, '-': <built-in function neg>}

単項演算子のデフォルトのコールバックテーブル。 このコピーは、サンドボックス環境の各インスタンスでunop_tableとして入手できます。

intercepted_binops: FrozenSet[str] = frozenset({})

インターセプトする必要のある二項演算子のセット。 このセットに追加された各演算子(デフォルトでは空)は、演算子を実行する call_binop()メソッドに委任されます。 デフォルトの演算子コールバックはbinop_tableで指定されています。

次の二項演算子はインターセプト可能です://%+*-/、および**

演算子テーブルのデフォルトの操作は、組み込み関数に対応しています。 傍受された通話は常にネイティブのオペレーター通話よりも遅いため、関心のある通話のみを傍受するようにしてください。

バージョン2.6の新機能。

intercepted_unops: FrozenSet[str] = frozenset({})

インターセプトする必要がある単項演算子のセット。 このセットに追加された各演算子(デフォルトでは空)は、演算子を実行する call_unop()メソッドに委任されます。 デフォルトの演算子コールバックはunop_tableで指定されています。

次の単項演算子はインターセプト可能です:+-

演算子テーブルのデフォルトの操作は、組み込み関数に対応しています。 傍受された通話は常にネイティブのオペレーター通話よりも遅いため、関心のある通話のみを傍受するようにしてください。

バージョン2.6の新機能。

is_safe_attribute(obj, attr, value)

サンドボックス環境はこのメソッドを呼び出して、オブジェクトの属性に安全にアクセスできるかどうかを確認します。 デフォルトでは、アンダースコアで始まるすべての属性は、 is_internal_attribute()関数によって返される内部pythonオブジェクトの特別な属性と同様にプライベートと見なされます。

パラメーター
  • objAny )–

  • attrstr )–

  • 任意)–

リターンタイプ

ブール

is_safe_callable(obj)

オブジェクトが安全に呼び出せるかどうかを確認してください。 デフォルトでは、 unsafe()で装飾されていない限り、呼び出し可能オブジェクトは安全であると見なされます。

これは、func.alters_data = Trueを設定するDjangoの規則も認識します。

パラメーター

objAny )–

リターンタイプ

ブール

class jinja2.sandbox.ImmutableSandboxedEnvironment([options])
通常の SandboxedEnvironment とまったく同じように機能しますが、 list 、 set 、および dict を使用して変更することはできません。 X186X] modify_known_mutable()関数。
パラメーター
;;* argsAny )–
  • kwargsAny )–
リターンタイプ
なし
exception jinja2.sandbox.SecurityError(message=None)
サンドボックスが有効になっている場合に、テンプレートが安全でないことを行おうとした場合に発生します。
パラメーター
メッセージオプション [ str ] )–
リターンタイプ
なし
jinja2.sandbox.unsafe(f)
関数またはメソッドを安全でないものとしてマークします。
パラメーター
fjinja2.sandbox.F )–
リターンタイプ
jinja2.sandbox.F
jinja2.sandbox.is_internal_attribute(obj, attr)

指定された属性が内部python属性であるかどうかをテストします。 たとえば、この関数は、Pythonオブジェクトの func_code 属性に対して True を返します。 これは、環境メソッド is_safe_attribute()がオーバーライドされている場合に役立ちます。

>>> from jinja2.sandbox import is_internal_attribute
>>> is_internal_attribute(str, "mro")
True
>>> is_internal_attribute(str, "upper")
False
パラメーター
  • objAny )–

  • attrstr )–

リターンタイプ

ブール

jinja2.sandbox.modifies_known_mutable(obj, attr)

この関数は、組み込みの可変オブジェクト(list、dict、set、またはdeque)または対応するABCの属性が呼び出された場合にそれを変更するかどうかをチェックします。

>>> modifies_known_mutable({}, "clear")
True
>>> modifies_known_mutable({}, "keys")
False
>>> modifies_known_mutable([], "append")
True
>>> modifies_known_mutable([], "index")
False

サポートされていないオブジェクトで呼び出された場合、Falseが返されます。

>>> modifies_known_mutable("foo", "upper")
False
パラメーター
  • objAny )–

  • attrstr )–

リターンタイプ

ブール

ノート

Jinjaサンドボックスだけでは、完全なセキュリティを実現するソリューションはありません。 特にWebアプリケーションの場合、ユーザーが任意のHTMLを使用してテンプレートを作成する可能性があるため、(同じサーバーで複数のユーザーを実行している場合)JavaScriptの挿入などによって相互に害を及ぼさないようにすることが重要です。 。

また、サンドボックスは構成と同じくらい良いだけです。 非共有リソースのみをテンプレートに渡し、属性に何らかのホワイトリストを使用することを強くお勧めします。

また、テンプレートによってランタイムエラーやコンパイル時エラーが発生する可能性があることにも注意してください。必ずそれらをキャッチしてください。


オペレーターの傍受

バージョン2.6の新機能。


最高のパフォーマンスを実現するために、Jinjaではオペレーターがタイプ固有のコールバックメソッドを直接呼び出すことができます。 これは、Environment.call()をオーバーライドしてこれを傍受することはできないことを意味します。 さらに、演算子の動作方法により、演算子から特別なメソッドへの変換が常に直接可能であるとは限りません。 たとえば、分割の場合、複数の特別なメソッドが存在します。

Jinja 2.6では、明示的な演算子インターセプトがサポートされるようになりました。 これは、必要に応じて特定の演算子をカスタマイズするために使用できます。 オペレーターをインターセプトするには、 SandboxedEnvironment.intercepted_binops 属性をオーバーライドする必要があります。 インターセプトする必要のある演算子がそのセットに追加されると、Jinjaは SandboxedEnvironment.call_binop()関数を呼び出すバイトコードを生成します。 単項演算子の場合、代わりに unary 属性とメソッドを使用する必要があります。

SandboxedEnvironment.call_binop のデフォルトの実装では、SandboxedEnvironment.binop_tableを使用して、演算子シンボルをデフォルトの演算子動作を実行するコールバックに変換します。

この例は、Jinjaで電源(**)演算子を無効にする方法を示しています。

from jinja2.sandbox import SandboxedEnvironment


class MyEnvironment(SandboxedEnvironment):
    intercepted_binops = frozenset(['**'])

    def call_binop(self, context, operator, left, right):
        if operator == '**':
            return self.undefined('the power operator is unavailable')
        return SandboxedEnvironment.call_binop(self, context,
                                               operator, left, right)

呼び出しをインターセプトしていない場合でも、必ずスーパーメソッドを呼び出してください。 Jinjaは、式を評価するためにメソッドを内部的に呼び出す場合があります。