Piaskownica
Sandbox zapewnia warstwę bezpieczeństwa, która daje kontrolę nad tym, jakie znaczniki, funkcje PHP, metody itp. mogą być używane w szablonach. Dzięki trybowi piaskownicy możesz bezpiecznie współpracować z klientem lub zewnętrznym koderem przy tworzeniu szablonów bez obaw o kompromitację aplikacji lub niepożądane operacje.
Jak to działa? Po prostu definiujemy, na co chcemy zezwolić w szablonie. Na początku wszystko jest zabronione i stopniowo
przyznajemy uprawnienia. Poniższy kod zezwala szablonowi na używanie tagów {block}
, {if}
,
{else}
i {=}
(ten ostatni jest tagiem do drukowania 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();
Aby upewnić się, że użytkownik nie wstawi na stronę kodu PHP, który jest poprawny składniowo, ale zabroniony i powoduje błąd kompilacji PHP, zalecamy sprawdzanie szablonów przez linter PHP. Możesz aktywować tę funkcjonalność za pomocą metody Engine::enablePhpLint(). Ponieważ musi ona wywołać plik binarny PHP w celu sprawdzenia, należy przekazać jego ścieżkę jako parametr:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');