(PECL runkit >= 0.7.0)
Runkit_Sandbox — Runkit Sandbox クラス -- PHP バーチャルマシン
Runkit_Sandbox クラスをインスタンス化すると、 独自のスコープとプログラムスタックを持つ新しいスレッドが生成されます。 コンストラクタに渡すオプションを設定することで、この環境では インタプリタの機能を制限することが可能す。そのため、ユーザから渡された コードを実行する場合などに、より安全な環境を提供可能です。
注意: サンドボックスのサポート (runkit_lint(), runkit_lint_file(), および Runkit_Sandbox クラスで使用)は、 PHP 5.1.0 以降または特別なパッチを適用した PHP 5.0 でのみ利用可能であり、スレッドセーフを有効にしておく必要があります。 詳細については、runkit パッケージに含まれる README ファイルを参照してください。
options は連想配列で、その中に 以下の ini オプションの組み合わせを格納します。
Runkit_Sandbox クラスをインスタンス化した 外部スクリプトが safe_mode = off と設定されている 場合、サンドボックス内の safe_mode を on にすることが可能です。 外部スクリプトで safe_mode が有効になっている 場合に、サンドボックス内でそれを無効にすることはできません。
Runkit_Sandbox クラスをインスタンス化した 外部スクリプトが safe_mode_gid = on と設定されている 場合、サンドボックス内の safe_mode_gid を off にすることが可能です。 外部スクリプトで safe_mode_gid が無効になっている 場合に、サンドボックス内でそれを有効にすることはできません。
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 が指定されていない場合、それはルートディレクトリと判断され、 どの場所でも指定可能となります。
safe_mode と同様、より厳しくする方向にのみ 指定可能です。この場合は TRUE と指定されている場合に FALSE を 指定することが可能となります。
サンドボックス内のインタプリタで無効とする関数を、カンマ区切りの リストで指定します。現在すでに無効になっている関数名を含める必要は ありません。それらはリストに載っているか否かにかかわらず無効となります。
サンドボックス内のインタプリタで無効とするクラスを、カンマ区切りの リストで指定します。現在すでに無効になっているクラス名を含める必要は ありません。それらはリストに載っているか否かにかかわらず無効となります。
サンドボックス内のインタプリタでスーパーグローバルとして扱う変数を、 カンマ区切りのリストで指定します。これらの変数は、既に内部で 定義されている変数やグローバルの runkit.superglobal 設定に 追加して使用されます。
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)
サンドボックス内で定義されている関数は、すべてサンドボックス オブジェクトのメソッドとしてコールできます。これには、擬似関数として 扱われる以下のような言語構造も含みます。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 は通常の配列オフセットと同様に読み書きが可能です。 将来的には書き込み専用の設定項目も現れるかもしれませんが、 今のところはそのような項目はありません。
設定 | 型 | 目的 | デフォルト |
---|---|---|---|
active | Boolean (Read Only) | サンドボックスが使用可能な状態である場合に TRUE 、 die() や exit() のコールもしくは致命的なエラーなどで リクエストから抜けた状態である場合に FALSE 。 | TRUE (Initial) |
output_handler | Callback | 有効なコールバックを指定すると、サンドボックス インスタンスの生成するすべての出力に対してその 関数が適用されます。 サンドボックス出力ハンドラは、システム全体の 出力ハンドラと同じ呼び出し規約に従います。 | なし |
parent_access | Boolean | サンドボックスが Runkit_Sandbox_Parent クラスのインスタンスを使用するかどうか。使用するには、 その他の Runkit_Sandbox_Parent 関連の設定を有効にする必要があります。 | FALSE |
parent_read | Boolean | サンドボックスが親コンテキストの変数を読み込むかどうか。 | FALSE |
parent_write | Boolean | サンドボックスが親コンテキストの変数を変更するかどうか。 | FALSE |
parent_eval | Boolean | サンドボックスが親コンテキストの任意のコードを評価する(evaluate) かどうか。危険です。 | FALSE |
parent_include | Boolean | サンドボックスが親コンテキストの php ファイルを include するかどうか。 危険です。 | FALSE |
parent_echo | Boolean | サンドボックスが親コンテキストのデータを表示する際に、それ自身の 出力ハンドラを回避するかどうか。 | FALSE |
parent_call | Boolean | サンドボックスが親コンテキストの関数をコールするかどうか。 | FALSE |
parent_die | Boolean | サンドボックスが親コンテキスト(そして自分自身)を終了させるかどうか。 | FALSE |
parent_scope | Integer | 親のプロパティに対してどのようなスコープでアクセスするか。 0 == Global scope, 1 == Calling scope, 2 == Scope preceeding calling scope, 3 == The scope before that, etc..., etc... | 0 (Global) |
parent_scope | String | parent_scope に文字列値が設定されている場合は、 グローバルスコープの配列変数名を表します。アクセス時にその名前の 変数が存在しない場合は、空の配列が作成されます。変数が存在するが 配列ではない場合は、その変数への参照を含むダミー配列が作成されます。 |