Sandkasten

Sandbox bietet eine Sicherheitsebene, die Ihnen die Kontrolle darüber gibt, welche Tags, PHP-Funktionen, Methoden usw. in Vorlagen verwendet werden können. Dank des Sandbox-Modus können Sie bei der Vorlagenerstellung sicher mit einem Kunden oder einem externen Programmierer zusammenarbeiten, ohne sich Gedanken über eine Beeinträchtigung der Anwendung oder unerwünschte Vorgänge zu machen.

Wie funktioniert das? Wir legen einfach fest, was wir in der Vorlage erlauben wollen. Am Anfang ist alles verboten, und wir geben nach und nach die Berechtigungen frei. Der folgende Code erlaubt der Vorlage die Verwendung der Tags {block}, {if}, {else} und {=} (letzteres ist ein Tag zum Drucken einer Variablen oder eines Ausdrucks) sowie aller Filter:

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

$latte->setPolicy($policy);

Wir können auch den Zugriff auf globale Funktionen, Methoden oder Eigenschaften von Objekten erlauben:

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

Ist das nicht erstaunlich? Sie können alles auf einer sehr niedrigen Ebene kontrollieren. Wenn die Vorlage versucht, eine nicht zugelassene Funktion aufzurufen oder auf eine nicht zugelassene Methode oder Eigenschaft zuzugreifen, löst sie die Ausnahme Latte\SecurityViolationException aus.

Die Erstellung von Richtlinien von Grund auf, wenn alles verboten ist, ist vielleicht nicht sehr bequem, daher können Sie von einer sicheren Grundlage ausgehen:

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

Das bedeutet, dass alle Standard-Tags erlaubt sind mit Ausnahme von contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint, widget. Alle Standardfilter sind ebenfalls erlaubt, mit Ausnahme von datastream, noescape und nocheck. Schließlich ist auch der Zugriff auf die Methoden und Eigenschaften des Objekts $iterator erlaubt.

Die Regeln gelten für die Vorlage, die wir mit dem neuen {sandbox} Tag einfügen. Das ist so etwas wie {include}, aber es schaltet den Sandbox-Modus ein und übergibt auch keine externen Variablen:

{sandbox 'untrusted.latte'}

Das Layout und die einzelnen Seiten können also alle Tags und Variablen wie bisher verwenden, Einschränkungen gelten nur für die Vorlage untrusted.latte.

Einige Verstöße, wie die Verwendung eines verbotenen Tags oder Filters, werden zur Kompilierzeit erkannt. Andere, wie z. B. der Aufruf nicht erlaubter Methoden eines Objekts, zur Laufzeit. Die Vorlage kann auch beliebige andere Fehler enthalten. Um zu verhindern, dass eine Ausnahme von der Sandbox-Vorlage ausgelöst wird, die das gesamte Rendering unterbricht, können Sie einen eigenen Exception-Handler definieren, der die Ausnahme z. B. nur protokolliert.

Wenn wir den Sandbox-Modus direkt für alle Vorlagen einschalten wollen, ist das ganz einfach:

$latte->setSandboxMode();

Um sicherzustellen, dass ein Benutzer keinen syntaktisch korrekten, aber verbotenen PHP-Code in die Seite einfügt, der einen PHP-Compile-Fehler verursacht, empfehlen wir, Vorlagen durch den PHP-Linter überprüfen zu lassen. Sie können diese Funktionalität mit der Methode Engine::enablePhpLint() aktivieren. Da sie für die Prüfung das PHP-Binary aufrufen muss, übergeben Sie dessen Pfad als Parameter:

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