Bac à sable

Sandbox fournit une couche de sécurité qui vous permet de contrôler les balises, les fonctions PHP, les méthodes, etc. qui peuvent être utilisées dans les modèles. Grâce au mode bac à sable, vous pouvez collaborer en toute sécurité avec un client ou un codeur externe sur la création de modèles sans craindre de compromettre l'application ou d'effectuer des opérations non souhaitées.

Comment cela fonctionne-t-il ? Nous définissons simplement ce que nous voulons autoriser dans le modèle. Au début, tout est interdit et nous accordons progressivement des permissions. Le code suivant permet au modèle d'utiliser les balises {block}, {if}, {else} et {=} (cette dernière est une balise permettant d'imprimer 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);

Nous pouvons également autoriser l'accès aux fonctions, méthodes ou propriétés globales des objets :

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

N'est-ce pas incroyable ? Vous pouvez tout contrôler à un niveau très bas. Si le modèle tente d'appeler une fonction non autorisée ou d'accéder à une méthode ou une propriété non autorisée, il lève l'exception Latte\SecurityViolationException.

Créer des politiques à partir de zéro, lorsque tout est interdit, peut ne pas être pratique, vous pouvez donc commencer à partir d'une base sûre :

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

Cela signifie que toutes les balises standard sont autorisées, sauf contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint, widget. Tous les filtres standard sont également autorisés, à l'exception de datastream, noescape et nocheck. Enfin, l'accès aux méthodes et aux propriétés de l'objet $iterator est également autorisé.

Les règles s'appliquent au modèle que nous insérons avec la nouvelle balise {sandbox} avec la nouvelle balise. Il s'agit d'un modèle semblable à {include}, mais qui active le mode “sandbox” et ne transmet pas de variables externes :

{sandbox 'untrusted.latte'}

Ainsi, la mise en page et les pages individuelles peuvent utiliser toutes les balises et variables comme auparavant, les restrictions ne seront appliquées qu'au modèle untrusted.latte.

Certaines violations, 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 non autorisées d'un objet, au moment de l'exécution. Le modèle peut également contenir d'autres bogues. Afin d'éviter qu'une exception ne soit levée à partir du modèle sandboxé, ce qui perturbe l'ensemble du rendu, vous pouvez définir votre propre gestionnaire d'exception, qui, par exemple, se contente de l'enregistrer.

Si nous voulons activer le mode sandbox directement pour tous les modèles, c'est facile :

$latte->setSandboxMode();

Pour s'assurer qu'un utilisateur n'insère pas dans la page un code PHP syntaxiquement correct mais interdit et provoquant une erreur de compilation PHP, nous recommandons de faire vérifier les modèles par le linter PHP. Vous pouvez activer cette fonctionnalité en utilisant la méthode Engine::enablePhpLint(). Puisqu'elle doit appeler le binaire PHP pour la vérification, passez son chemin en paramètre :

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