Web aym.pekori.to

Runkit_Sandbox

(no version information, might be only in CVS)

Runkit_Sandbox --  Runkit Sandbox クラス -- PHP バーチャルマシン

説明

Runkit_Sandbox クラスをインスタンス化すると、 独自のスコープとプログラムスタックを持つ新しいスレッドが生成されます。 コンストラクタに渡すオプションを設定することで、この環境では インタプリタの機能を制限することが可能す。そのため、ユーザから渡された コードを実行する場合などに、より安全な環境を提供可能です。

注意: サンドボックスのサポート (runkit_lint(), runkit_lint_file(), および Runkit_Sandbox クラスで使用)は、PHP 5.1 以降または特別なパッチを適用した PHP 5.0 でのみ利用可能であり、スレッドセーフを有効にしておく必要があります。 詳細については、runkit パッケージに含まれる README ファイルを参照してください。

コンストラクタ

void Runkit_Sandbox::__construct ( [array options] )

options は連想配列で、その中に 以下の ini オプションの組み合わせを格納します。

safe_mode

Runkit_Sandbox クラスをインスタンス化した 外部スクリプトが safe_mode = off と設定されている 場合、サンドボックス内の safe_mode を on にすることが可能です。 外部スクリプトで safe_mode が有効になっている 場合に、サンドボックス内でそれを無効にすることはできません。

safe_mode_gid

Runkit_Sandbox クラスをインスタンス化した 外部スクリプトが safe_mode_gid = on と設定されている 場合、サンドボックス内の safe_mode_gid を off にすることが可能です。 外部スクリプトで safe_mode_gid が無効になっている 場合に、サンドボックス内でそれを有効にすることはできません。

safe_mode_include_dir

Runkit_Sandbox クラスをインスタンス化した 外部スクリプトが safe_mode_include_dir を 組み込んで configure されていた場合、サンドボックス内の safe_mode_include_dir を定義されているディレクトリ以下に指定することが 可能です。この機能を無効にすることを示すため、safe_mode_include_dir をクリアすることも可能です。 外部スクリプトで safe_mode_include_dir が空白になっているが safe_mode は有効でない場合、任意の safe_mode_include_dir を 指定して safe_mode を on にすることが可能です。

open_basedir

open_basedir は、カレントの open_basedir 以下の任意のパスを指定可能です。 グローバルスコープで open_basedir が指定されていない場合、それはルートディレクトリと判断され、 どの場所でも指定可能となります。

allow_url_fopen

safe_mode と同様、より厳しくする方向にのみ 指定可能です。この場合は TRUE と指定されている場合に FALSE を 指定することが可能となります。

disable_functions

サンドボックス内のインタプリタで無効とする関数を、カンマ区切りの リストで指定します。現在すでに無効になっている関数名を含める必要は ありません。それらはリストに載っているか否かにかかわらず無効となります。

disable_classes

サンドボックス内のインタプリタで無効とするクラスを、カンマ区切りの リストで指定します。現在すでに無効になっているクラス名を含める必要は ありません。それらはリストに載っているか否かにかかわらず無効となります。

runkit.superglobal

サンドボックス内のインタプリタでスーパーグローバルとして扱う変数を、 カンマ区切りのリストで指定します。これらの変数は、既に内部で 定義されている変数やグローバルの runkit.superglobal 設定に 追加して使用されます。

runkit.internal_override

Ini オプション runkit.internal_override は、 サンドボックス内では無効になる(そして、再度有効にはならない) かもしれません。

例 1. 機能を制限したサンドボックスのインスタンス化

<?php
$options
= array(
  
'safe_mode'=>true,
  
'open_basedir'=>'/var/www/users/jdoe/',
  
'allow_url_fopen'=>'false',
  
'disable_functions'=>'exec,shell_exec,passthru,system',
  
'disable_classes'=>'myAppClass');
$sandbox = new Runkit_Sandbox($options);
/* 制限されていない ini 項目は、普通に設定できる */
$sandbox->ini_set('html_errors',true);
?>

変数へのアクセス

サンドボックス環境内のすべてのグローバル変数は、サンドボックス オブジェクトのプロパティとしてアクセス可能です。しかし、 オブジェクト変数やりソース変数はインタプリタ越しに 利用することができないことに注意しましょう。これは、これらの 2 つのスレッドのメモリ管理が仮想マシン上で行われていることが原因です。 さらに、配列はすべてディープコピーされ、参照渡しのデータは 失われます。つまり、参照渡しのデータをインタプリタ越しに使用することは できないということです。

例 2. サンドボックス内部の変数の扱い

<?php
$sandbox
= new Runkit_Sandbox();

$sandbox->foo = 'bar';
$sandbox->eval('echo "$foo\n"; $bar = $foo . "baz";');
echo
"{$sandbox->bar}\n";
if (isset(
$sandbox->foo)) unset($sandbox->foo);
$sandbox->eval('var_dump(isset($foo));');
?>

上の例の出力は以下となります。

bar
barbaz
bool(false)

PHP 関数のコール

サンドボックス内で定義されている関数は、すべてサンドボックス オブジェクトのメソッドとしてコールできます。これには、擬似関数として 扱われる以下のような言語構造も含みます。eval()include()include_once()require()require_once()echo()print()die() および exit()

例 3. サンドボックス内の関数のコール

<?php
$sandbox
= new Runkit_Sandbox();

echo
$sandbox->str_replace('a','f','abc');
?>

上の例の出力は以下となります。

fbc

サンドボックス内の関数への引数は、外部の PHP インスタンスから 渡されます。もしサンドボックスのスコープから引数を渡したい場合は、 上で示したようにサンドボックスのプロパティとしてそれにアクセスする ようにしてください。

例 4. サンドボックス内の関数に引数を渡す

<?php
$sandbox
= new Runkit_Sandbox();

$foo = 'bar';
$sandbox->foo = 'baz';
echo
$sandbox->str_replace('a',$foo,'a');
echo
$sandbox->str_replace('a',$sandbox->foo,'a');
?>

上の例の出力は以下となります。

bar
baz

サンドボックス設定の変更

runkit バージョン 0.5 以降では、配列へのアクセスと同じ構文で、 実行時にサンドボックスの一部の設定を変更することが可能です。 active は読み込み専用で、現在の状態に ついての情報を提供します。output_handler は通常の配列オフセットと同様に読み書きが可能です。 将来的には書き込み専用の設定項目も現れるかもしれませんが、 今のところはそのような項目はありません。

表 1. サンドボックス設定 / 状態のインジケータ

設定目的デフォルト
activeBoolean (Read Only) サンドボックスが使用可能な状態である場合に TRUE 、 die() や exit() のコールもしくは致命的なエラーなどで リクエストから抜けた状態である場合に FALSETRUE (Initial)
output_handlerCallback 有効なコールバックを指定すると、サンドボックス インスタンスの生成するすべての出力に対してその 関数が適用されます。 サンドボックス出力ハンドラは、システム全体の 出力ハンドラと同じ呼び出し規約に従います。 なし
parent_accessBoolean サンドボックスが Runkit_Sandbox_Parent クラスのインスタンスを使用するかどうか。使用するには、 その他の Runkit_Sandbox_Parent 関連の設定を有効にする必要があります。 FALSE
parent_readBoolean サンドボックスが親コンテキストの変数を読み込むかどうか。 FALSE
parent_writeBoolean サンドボックスが親コンテキストの変数を変更するかどうか。 FALSE
parent_evalBoolean サンドボックスが親コンテキストの任意のコードを評価する(evaluate) かどうか。危険です。 FALSE
parent_includeBoolean サンドボックスが親コンテキストの php ファイルを include するかどうか。 危険です。 FALSE
parent_echoBoolean サンドボックスが親コンテキストのデータを表示する際に、それ自身の 出力ハンドラを回避するかどうか。 FALSE
parent_callBoolean サンドボックスが親コンテキストの関数をコールするかどうか。 FALSE
parent_dieBoolean サンドボックスが親コンテキスト(そして自分自身)を終了させるかどうか。 FALSE
parent_scopeInteger 親のプロパティに対してどのようなスコープでアクセスするか。 0 == Global scope, 1 == Calling scope, 2 == Scope preceeding calling scope, 3 == The scope before that, etc..., etc... 0 (Global)
parent_scopeString parent_scope に文字列値が設定されている場合は、 グローバルスコープの配列変数名を表します。アクセス時にその名前の 変数が存在しない場合は、空の配列が作成されます。変数が存在するが 配列ではない場合は、その変数への参照を含むダミー配列が作成されます。