Cajón de arena
Sandbox proporciona una capa de seguridad que te permite controlar qué etiquetas, funciones PHP, métodos, etc. se pueden utilizar en las plantillas. Gracias al modo sandbox, puedes colaborar de forma segura con un cliente o codificador externo en la creación de plantillas sin preocuparte de comprometer la aplicación o de operaciones no deseadas.
¿Cómo funciona? Simplemente definimos lo que queremos permitir en la plantilla. Al principio todo está prohibido y poco a
poco vamos concediendo permisos. El siguiente código permite a la plantilla utilizar las etiquetas {block}
,
{if}
, {else}
y {=}
(esta última es una 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);
También podemos permitir el acceso a funciones globales, métodos o propiedades de objetos:
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
¿No es increíble? Puedes controlarlo todo a un nivel muy bajo. Si la plantilla intenta llamar a una función no autorizada
o acceder a un método o propiedad no autorizados, lanza la excepción Latte\SecurityViolationException
.
Crear políticas desde cero, cuando todo está prohibido, puede no ser conveniente, así que puedes empezar desde una base segura:
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
Esto 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
. También se permiten todos los filtros estándar excepto datastream
, noescape
y
nocheck
. Por último, también se permite el acceso a los métodos y propiedades del objeto
$iterator
.
Las reglas se aplican a la plantilla que insertamos con la nueva etiqueta {sandbox}
etiqueta. Que es algo así como {include}
, pero
activa el modo sandbox y además no pasa ninguna variable externa:
{sandbox 'untrusted.latte'}
Así, el diseño y las páginas individuales pueden utilizar todas las etiquetas y variables como antes, las restricciones se
aplicarán sólo a la plantilla untrusted.latte
.
Algunas infracciones, como el uso de una etiqueta o filtro prohibidos, se detectan en tiempo de compilación. Otras, como la llamada a métodos no permitidos de un objeto, en tiempo de ejecución. La plantilla también puede contener cualquier otro error. Para evitar que se lance una excepción desde la plantilla sandboxed, lo que interrumpe toda la renderización, puedes definir tu propio manejador de excepciones, que, por ejemplo, se limita a registrarla.
Si queremos activar el modo sandbox directamente para todas las plantillas, es fácil:
$latte->setSandboxMode();
Para asegurar que un usuario no inserte código PHP en la página que sea sintácticamente correcto pero prohibido y cause un Error de Compilación PHP, recomendamos tener plantillas comprobadas por el linter PHP. Puede activar esta funcionalidad usando el método Engine::enablePhpLint(). Dado que necesita llamar al binario PHP para la comprobación, pase su ruta como parámetro:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');