Sandbox
Sandbox fornece uma camada de segurança que lhe dá controle sobre quais tags, funções PHP, métodos, etc. podem ser usados nos modelos. Graças ao modo sandbox, você pode colaborar com segurança com um cliente ou codificador externo na criação de modelos sem se preocupar em comprometer a aplicação ou operações indesejadas.
Como isso funciona? 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 use as tags {block}
, {if}
,
{else}
e {=}
(a ú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();
Para garantir que um usuário não insira código PHP na página que esteja sintaticamente correto, mas que seja proibido e cause um erro de compilação do PHP, recomendamos que os modelos sejam verificados pelo linter do PHP. Você pode ativar essa funcionalidade usando o método Engine::enablePhpLint(). Como ele precisa chamar o binário do PHP para a verificação, passe seu caminho como parâmetro:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');