Песочница
У Latte есть бронированная крепость прямо под капотом. Он называется режимом песочницы и является важной функцией, которая защищает приложения, использующие шаблоны из ненадежных источников. Например, когда они редактируются самими пользователями.
Режим песочницы следит за тем, чтобы песок не высыпался из коробки. Таким образом, он обеспечивает ограниченный доступ к тегам, фильтрам, функциям, методам и т.д. Как это работает? Мы просто определяем, что мы хотим разрешить в шаблоне. Вначале все запрещено, и постепенно мы предоставляем разрешения:
Следующий код разрешает шаблону использовать теги {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();