Sandbox
Sandboxは、テンプレートで使用できるタグ、PHP関数、メソッドなどを制御できるセキュリティ層を提供します。Sandboxモードのおかげで、アプリケーションの侵害や望ましくない操作を心配することなく、クライアントや外部コーダーと安全にテンプレート作成で協力できます。
どのように機能しますか?単に、テンプレートに許可するものをすべて定義します。デフォルトではすべてが禁止されており、徐々に許可していきます。次のコードでは、テンプレートの作成者がタグ
{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}
タグで挿入するテンプレートに自動的に適用されるわけではありません。{sandbox}
タグは、そのインクルードされたテンプレートに対して独立したサンドボックスインスタンス(デフォルトでは安全なポリシーを使用)を作成します。
{sandbox 'untrusted.latte'}
したがって、レイアウトと個々のページはすべてのタグと変数を自由に利用できますが、untrusted.latte
テンプレートにのみ制限が適用されます。
禁止されたタグやフィルタの使用など、一部の違反はコンパイル時に検出されます。オブジェクトの許可されていないメソッドの呼び出しなど、他の違反は実行時に検出されます。 テンプレートには他のエラーも含まれる可能性があります。サンドボックス化されたテンプレートから例外が発生してレンダリング全体が中断されないように、カスタム例外ハンドラを定義して、例えばそれをログに記録することができます。
すべてのテンプレートに対してグローバルにサンドボックスモードを有効にしたい場合は、setSandboxMode(true)
を呼び出し、setPolicy()
でポリシーを設定します:
$latte->setSandboxMode();
ユーザーがページに、構文的には正しいが禁止されておりPHPコンパイルエラーを引き起こすPHPコードを挿入しないことを確認するために、PHPリンターでテンプレートをチェックすることをお勧めします。この機能は
Engine::enablePhpLint()
メソッドで有効にします。チェックにはPHPバイナリを呼び出す必要があるため、そのパスをパラメータとして渡します:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');