サンドボックス
サンドボックスは、テンプレートで使用できるタグ、PHP関数、メソッドなどを制御できるセキュリティレイヤーを提供します。サンドボックスモードのおかげで、アプリケーションの破損や不要な操作を心配することなく、クライアントや外部のコーダーとテンプレート作成で安全に共同作業することができます。
どのように機能するのか?テンプレートで許可したいものを定義するだけです。最初はすべてが禁止されており、徐々に許可を与えていきます。以下のコードでは、{block}
、{if}
、{else}
、{=}
のタグ(後者は変数や式を表示するためのタグ)とすべてのフィルターの使用を許可しています:
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$latte->setPolicy($policy);
また、グローバルな関数、メソッド、オブジェクトのプロパティへのアクセスも許可することができます。
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
これってすごいことだと思いませんか?非常に低いレベルですべてをコントロールすることができるのです。もしテンプレートが未承認の関数を呼び出したり、未承認のメソッドやプロパティにアクセスしようとすると、例外がスローされますLatte\SecurityViolationException
.
すべてが禁止された状態でゼロからポリシーを作成するのは不便なので、安全な基礎から始めることができます。
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
これは、contentType
,debugbreak
,dump
,extends
,import
,include
,layout
,php
,sandbox
,snippet
,snippetArea
,templatePrint
,varPrint
,widget
を除いて、すべての標準タグが許可されていることを意味します。
datastream
,noescape
,nocheck
を除くすべての標準的なフィルタも許可されています。最後に、オブジェクト$iterator
のメソッドとプロパティへのアクセスも許可されています。
このルールは、新しい {sandbox}
タグで挿入されるテンプレートにも適用されます。これは{include}
のようなものですが、サンドボックスモードをオンにし、外部変数を一切渡さないようにしています。
{sandbox 'untrusted.latte'}
したがって、レイアウトと個々のページは、以前のようにすべてのタグと変数を使用することができ、制限はテンプレートにのみ適用されますuntrusted.latte
.
禁止されているタグやフィルタの使用など、一部の違反はコンパイル時に検出されます。また、オブジェクトの許可されていないメソッドを呼び出すなどの違反は、実行時に検出されます。 テンプレートは、その他のバグを含むこともできます。サンドボックス化されたテンプレートから例外が発生し、レンダリング全体が中断するのを防ぐために、独自の例外ハンドラを定義し、例えば、単にログを記録することができます。
すべてのテンプレートに対して直接サンドボックスモードをオンにしたい場合は、簡単です。
$latte->setSandboxMode();
ユーザが、構文的には正しいが禁止されている PHP コードをページに挿入して PHP Compile Error を発生させないようにするには、テンプレートを PHP リンターでチェックすることをお勧めします。この機能を有効にするには、Engine::enablePhpLint() メソッドを使用します。チェックのためにPHPバイナリを呼び出す必要があるので、そのパスをパラメータとして渡します:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');