17. 制限実行 (restricted execution)

警告: Python 2.3 では、既知の容易に修正できないセキュリティーホール のために、これらのモジュールは無効にされています。 rexecBastion モジュールを使った古いコード を読むときに助けになるよう、モジュールのドキュメントだけは 残されています。

制限実行 (restricted execution) とは、信頼できるコード と信頼できないコードを区別できるようにするための Python における 基本的なフレームワークです。このフレームワークは、信頼できる Python コード (スーパバイザ (supervisor)) が、 パーミッションに制限のかけられた ``拘束セル (padded cell)'' を生成し、このセル中で信頼のおけないコードを実行するという概念に 基づいています。信頼のおけないコードはこの拘束セルを破ることが できず、信頼されたコードで提供され、管理されたインタフェースを 介してのみ、傷つきやすいシステムリソースとやりとりすることができます。 ``制限実行'' という用語は、``安全な Python (safe-Python)'' を裏から支えるものです。というのは、真の安全を定義する ことは難しく、制限された環境を生成する方法によって決められるからです。 制限された環境は入れ子にすることができ、このとき内側のセルは より縮小されることはあるが決して拡大されることのない特権を持った サブセルを生成します。

Python の制限実行モデルの興味深い側面は、信頼されないコードに 提供されるインタフェースが、信頼されるコードに提供されるそれらと 同じ名前を持つということです。このため、制限された環境で動作 するよう設計されたコードを書く上で特殊なインタフェースを学ぶ 必要がありません。また、拘束セルの厳密な性質はスーパバイザによって 決められるため、アプリケーションによって異なる制限を課すことが できます。例えば、信頼されないコードが指定したディレクトリ内の 何らかのファイルを読み出すが決して書き込まないということが ``安全'' と考えられるかもしれません。この場合、スーパバイザは組み込みの open() 関数について、mode パラメタが 'w' の時に例外を送出するように再定義できます。また例えば、``安全'' とは、 filename パラメタに対して chroot() に似た 操作を施して、ルートパスがファイルシステム上の何らかの安全な ``砂場 (sandbox)'' 領域に対する相対パスになるようにすることかも しれません。この場合でも、信頼されないコードは依然として、 もとの呼び出しインタフェースを持ったままの組み込みのopen() 関数を制限環境中に見出します。ここでは、関数に対する意味付け (semantics) は同じですが、許可されないパラメタが使われようとしている とスーパバイザが判断した場合には IOError が送出されます。

Python のランタイムシステムは、特定のコードブロックが制限実行モード かどうかを、グローバル変数の中の __builtins__ オブジェクトの一意性をもとに判断します: オブジェクトが 標準の __builtin__ モジュール (の辞書) の場合、 コードは非制限下にあるとみなされます。それ以外は制限下にあると みなされます。

制限実行モードで動作する Python コードは、拘束セルから侵出しないように 設計された数多くの制限に直面します。例えば、関数オブジェクト 属性 func_globals や、クラスおよびインスタンスオブジェクトの 属性 __dict__ は利用できません。

二つのモジュールが、制限実行環境を立ち上げるためのフレームワークを 提供しています:

rexec   基本的な制限実行フレームワーク。
Bastion   オブジェクトに対するアクセスの制限を提供する。

参考資料:

Grail Home Page
Python で書かれたインターネットブラウザ Grail です。Python で書かれたアプレットをサポートするために、上記のモジュールを使っています。Grail における Python 制限実行モードの利用に関する詳しい情報は、Web サイトで入手することができます。
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。