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();