Sandkasten

Latte hat eine gepanzerte Festung direkt unter der Haube. Er wird Sandbox-Modus genannt und ist eine wichtige Funktion, die Anwendungen schützt, die Vorlagen aus nicht vertrauenswürdigen Quellen verwenden. Zum Beispiel, wenn sie von den Benutzern selbst bearbeitet werden.

Der Sandbox-Modus sorgt dafür, dass der Sand nicht aus der Kiste herauskommt. So bietet er einen eingeschränkten Zugriff auf Tags, Filter, Funktionen, Methoden usw. Wie funktioniert das? Wir legen einfach fest, was wir in der Vorlage zulassen 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) und 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();