Sandbox
Le Sandbox fournit une couche de sécurité qui vous donne le contrôle sur les balises, fonctions PHP, méthodes, etc. qui peuvent être utilisées dans les templates. Grâce au mode sandbox, vous pouvez collaborer en toute sécurité avec le client ou un codeur externe sur la création de templates, sans avoir à craindre que l'application soit compromise ou que des opérations indésirables soient effectuées.
Comment ça marche ? Nous définissons simplement tout ce que nous autorisons au template. Par défaut, tout est interdit et
nous autorisons progressivement. Le code suivant permet à l'auteur du template d'utiliser les balises {block}
,
{if}
, {else}
et {=}
, qui est la balise pour afficher une variable ou une expression et tous les filtres :
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$latte->setPolicy($policy);
Ensuite, nous pouvons autoriser des fonctions, méthodes ou propriétés d'objets individuelles :
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
N'est-ce pas merveilleux ? Vous pouvez contrôler absolument tout à un niveau très bas. Si le template tente d'appeler une
fonction non autorisée ou d'accéder à une méthode ou propriété non autorisée, cela se terminera par une exception
Latte\SecurityViolationException
.
Créer une politique à partir de zéro, où tout est interdit, peut ne pas être pratique, vous pouvez donc commencer à partir d'une base sûre :
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
Une base sûre signifie que toutes les balises standard sont autorisées sauf contentType
,
debugbreak
, dump
, extends
, import
, include
, layout
,
php
, sandbox
, snippet
, snippetArea
, templatePrint
,
varPrint
, widget
. Les filtres standard sont autorisés sauf datastream
,
noescape
et nocheck
. Et enfin, l'accès aux méthodes et propriétés de l'objet $iterator
est autorisé.
Les règles s'appliquent au template que nous insérons avec la balise {sandbox}
. C'est une sorte d'équivalent de
{include}
, qui active cependant le mode sécurisé et ne transmet également aucune variable :
{sandbox 'untrusted.latte'}
Ainsi, le layout et les pages individuelles peuvent utiliser sans interruption toutes les balises et variables, seules les
restrictions seront appliquées au template untrusted.latte
.
Certaines infractions, comme l'utilisation d'une balise ou d'un filtre interdit, sont détectées au moment de la compilation. D'autres, comme l'appel de méthodes d'objet non autorisées, seulement à l'exécution. Le template peut également contenir d'autres erreurs. Pour éviter qu'une exception provenant d'un template sandboxé ne perturbe l'ensemble du rendu, vous pouvez définir un gestionnaire d'exceptions personnalisé, qui la journalisera par exemple.
Si nous voulions activer le mode sandbox directement pour tous les templates, c'est facile :
$latte->setSandboxMode();
Pour être sûr que l'utilisateur n'insère pas dans la page du code PHP qui est syntaxiquement correct, mais interdit et
provoque une erreur de compilation PHP (PHP Compile Error), nous recommandons de faire vérifier les templates avec le linter PHP. Vous
activez cette fonctionnalité avec la méthode Engine::enablePhpLint()
. Comme elle a besoin d'appeler le binaire PHP
pour la vérification, passez son chemin en paramètre :
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');