Sandbox
Latte tem um bastião blindado diretamente sob o capô. É chamado de modo sandbox e é uma característica importante que protege as aplicações que utilizam gabaritos de fontes não confiáveis. Por exemplo, quando eles são editados pelos próprios usuários.
O modo Sandbox garante que a areia não saia da caixa. Assim, ele proporciona acesso limitado a tags, filtros, funções, métodos, etc. Como funciona? Nós simplesmente definimos o que queremos permitir no modelo. No início, tudo é proibido e gradualmente concedemos permissões:
O código a seguir permite que o modelo utilize as tags {block}
, {if}
, {else}
e
{=}
(esta última é uma tag para imprimir uma variável ou
expressão) e todos os filtros:
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$latte->setPolicy($policy);
Também podemos permitir o acesso a funções, métodos ou propriedades globais dos objetos:
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
Isso não é incrível? Você pode controlar tudo a um nível muito baixo. Se o modelo tentar chamar uma função não
autorizada ou acessar um método ou propriedade não autorizada, ele lança a exceção
Latte\SecurityViolationException
.
Criar políticas a partir do zero, quando tudo é proibido, pode não ser conveniente, para que você possa começar a partir de uma base segura:
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
Isto significa que todas as etiquetas padrão são permitidas exceto contentType
, debugbreak
,
dump
, import
, extends
, , include
, layout
, php
,
sandbox
, snippet
, , snippetArea
, templatePrint
, varPrint
,
widget
. Todos os filtros padrão também são permitidos, com exceção de datastream
,
noescape
e nocheck
. Finalmente, o acesso aos métodos e propriedades do objeto $iterator
também é permitido.
As regras se aplicam ao modelo que inserimos com o novo {sandbox}
tag. O que é algo como
{include}
, mas liga o modo sandbox e também não passa nenhuma variável externa:
{sandbox 'untrusted.latte'}
Assim, o layout e as páginas individuais podem usar todas as tags e variáveis como antes, as restrições serão aplicadas
apenas ao modelo untrusted.latte
.
Algumas violações, tais como o uso de uma etiqueta ou filtro proibido, são detectadas em tempo de compilação. Outras, como a chamada de métodos não permitidos de um objeto, em tempo de execução. O modelo também pode conter quaisquer outros bugs. A fim de evitar que uma exceção seja lançada a partir do template de caixa de areia, o que perturba toda a renderização, você pode definir seu próprio manipulador de exceções, que, por exemplo, apenas o registra.
Se quisermos ligar o modo sandbox diretamente para todos os gabaritos, é fácil:
$latte->setSandboxMode();