Sandbox

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 sandbox możesz bezpiecznie współpracować z klientem lub zewnętrznym koderem przy tworzeniu szablonów, nie martwiąc się o naruszenie aplikacji lub niepożądane operacje.

Jak to działa? Po prostu definiujemy, na co wszystko pozwalamy szablonowi. Przy czym domyślnie wszystko jest zabronione, a my stopniowo zezwalamy. Poniższym kodem umożliwimy autorowi szablonu używanie znaczników {block}, {if}, {else} i {=}, co jest znacznikiem do wyświetlania 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);

Dalej możemy zezwolić na poszczególne funkcje, metody lub właściwości obiektów:

$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 na bardzo niskim poziomie kontrolować absolutnie wszystko. Jeśli szablon spróbuje wywołać niedozwoloną funkcję lub uzyskać dostęp do niedozwolonej metody lub właściwości, zakończy się to wyjątkiem Latte\SecurityViolationException.

Tworzenie polityki od zera, gdy wszystko jest zabronione, może nie być wygodne, dlatego możesz zacząć od bezpiecznej podstawy:

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

Bezpieczna podstawa oznacza, że dozwolone są wszystkie standardowe znaczniki oprócz contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint, widget. Dozwolone są standardowe filtry oprócz datastream, noescape i nocheck. I na koniec dozwolony jest dostęp do metod i właściwości obiektu $iterator.

Zasady stosuje się do szablonu, który wstawiamy znacznikiem {sandbox}. Co jest pewnego rodzaju odpowiednikiem {include}, który jednak włącza tryb bezpieczny i nie przekazuje żadnych zmiennych:

{sandbox 'untrusted.latte'}

Zatem layout i poszczególne strony mogą swobodnie wykorzystywać wszystkie znaczniki i zmienne, jedynie na szablon untrusted.latte zostaną zastosowane restrykcje.

Niektóre naruszenia, takie jak użycie zabronionego znacznika lub filtra, zostaną wykryte w czasie kompilacji. Inne, takie jak wywołanie niedozwolonych metod obiektu, dopiero w czasie działania. Szablon może również zawierać dowolne inne błędy. Aby z sandboxowanego szablonu nie mógł wyskoczyć wyjątek, który zakłóci całe renderowanie, można zdefiniować własny niestandardowy handler wyjątków, który go na przykład zaloguje.

Jeśli chcielibyśmy włączyć tryb sandbox bezpośrednio dla wszystkich szablonów, jest to łatwe:

$latte->setSandboxMode();

Aby mieć pewność, że użytkownik nie wstawi do strony kodu PHP, który jest wprawdzie poprawny składniowo, ale zabroniony i spowoduje PHP Compile Error, zalecamy sprawdzać szablony za pomocą lintera PHP. Tę funkcjonalność włączysz metodą Engine::enablePhpLint(). Ponieważ do kontroli potrzebuje wywołać binarkę PHP, ścieżkę do niej przekaż jako parametr:

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