Piaskownica
Latte ma pancerny bunkier tuż pod maską. Nazywa się to trybem piaskownicy i jest ważną funkcją chroniącą aplikacje, które używają szablonów z niezaufanych źródeł. Na przykład wtedy, gdy są one edytowane przez samych użytkowników.
Sandbox oznacza piaskownicę, a ten tryb sprawia, że piasek nie dostaje się do wyznaczonego miejsca. Zapewnia więc ograniczony dostęp do makr, filtrów, funkcji, metod itp. Jak to działa? Po prostu określamy, na co wszystko pozwalamy szablonowi. W bazie wszystko jest zabronione i stopniowo pozwalamy na to:
Za pomocą poniższego kodu pozwalamy autorowi szablonu na użycie znaczników {block}
, {if}
,
{else}
, oraz {=}
, który jest znacznikiem służącym do wypisania zmiennej lub wyrażenia oraz wszystkich filtrów:
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$latte->setPolicy($policy);
Możemy również włączyć poszczególne funkcje, metody lub właściwości obiektu:
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
Czyż to nie wspaniałe? Możesz kontrolować wszystko na bardzo niskim poziomie. Jeśli szablon spróbuje wywołać
nielegalną funkcję lub uzyskać dostęp do nielegalnej metody lub właściwości, zakończy się wyjątkiem
Latte\SecurityViolationException
.
Tworzenie od podstaw polityki, w której wszystko jest zabronione, może nie być wygodne, więc można zacząć od bezpiecznej bazy:
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
Bezpieczna baza oznacza, że wszystkie standardowe tagi są dozwolone z wyjątkiem contentType
,
debugbreak
, dump
, extends
, import
, include
, layout
,
php
, sandbox
, snippet
, snippetArea
, templatePrint
,
varPrint
, widget
. Włączone są wszystkie standardowe filtry oprócz datastream
,
noescape
i nocheck
. Wreszcie włączony jest dostęp do metod i właściwości obiektu
$iterator
.
Reguły są stosowane do szablonu, który wstawiamy z tagiem {sandbox}
. Który jest w pewnym sensie podobny do
{include}
, ale włącza tryb bezpieczny i również nie przekazuje żadnych zmiennych:
{sandbox 'untrusted.latte'}
W ten sposób layout i poszczególne strony mogą bez przeszkód używać wszystkich znaczników i zmiennych, ograniczony
będzie jedynie szablon untrusted.latte
.
Niektóre przekroczenia, takie jak użycie zabronionego znacznika lub filtra, zostaną ujawnione w czasie kompilacji. Inne, takie jak wywoływanie nieautoryzowanych metod obiektu, tylko w czasie biegu. Szablon może zawierać również inne błędy. Aby zapobiec wyskakiwaniu wyjątku z sandboksowanego szablonu i zakłócaniu całego renderowania, możesz zdefiniować niestandardowy handler wyjątków, aby na przykład rejestrować wyjątek.
Gdybyśmy chcieli włączyć tryb piaskownicy bezpośrednio dla wszystkich szablonów, to łatwo to zrobić:
$latte->setSandboxMode();