Sandbox

Sandbox proporciona una capa de seguridad que le da control sobre qué etiquetas, funciones PHP, métodos, etc., se pueden usar en las plantillas. Gracias al modo sandbox, puede colaborar de forma segura con el cliente o un codificador externo en la creación de plantillas sin tener que preocuparse por violaciones de la aplicación u operaciones no deseadas.

¿Cómo funciona? Simplemente definimos todo lo que permitiremos en la plantilla. Por defecto, todo está prohibido y vamos permitiendo gradualmente. Con el siguiente código, permitimos al autor de la plantilla usar las etiquetas {block}, {if}, {else} y {=}, que es la etiqueta para imprimir una variable o expresión y todos los filtros:

$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);

$latte->setPolicy($policy);

Además, podemos permitir funciones, métodos o propiedades individuales de objetos:

$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);

¿No es asombroso? Puede controlar absolutamente todo a un nivel muy bajo. Si la plantilla intenta llamar a una función no permitida o acceder a un método o propiedad no permitidos, terminará con una excepción Latte\SecurityViolationException.

Crear una política desde cero, donde todo está prohibido, puede no ser cómodo, por lo que puede empezar desde una base segura:

$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();

La base segura significa que todas las etiquetas estándar están permitidas excepto contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint, widget. Están permitidos los filtros estándar excepto datastream, noescape y nocheck. Y finalmente, está permitido el acceso a los métodos y propiedades del objeto $iterator.

Las reglas se aplican a la plantilla que insertamos con la etiqueta {sandbox}. Que es algo análogo a {include}, pero que activa el modo seguro y tampoco pasa ninguna variable:

{sandbox 'untrusted.latte'}

Por lo tanto, el layout y las páginas individuales pueden usar libremente todas las etiquetas y variables, solo a la plantilla untrusted.latte se le aplicarán restricciones.

Algunas infracciones, como el uso de una etiqueta o filtro prohibido, se detectan en tiempo de compilación. Otras, como la llamada a métodos de objeto no permitidos, solo en tiempo de ejecución. La plantilla también puede contener cualquier otro error. Para evitar que una excepción de una plantilla en sandbox interrumpa todo el renderizado, puede definir un manejador de excepciones personalizado que, por ejemplo, la registre.

Si quisiéramos activar el modo sandbox directamente para todas las plantillas, es fácil:

$latte->setSandboxMode();

Para asegurarse de que el usuario no inserte en la página código PHP que sea sintácticamente correcto pero prohibido y cause un PHP Compile Error, recomendamos comprobar las plantillas con el linter PHP. Esta funcionalidad se activa con el método Engine::enablePhpLint(). Dado que necesita llamar al binario de PHP para la comprobación, pase la ruta como parámetro:

$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
versión: 3.0