Nette Documentation Preview

syntax
Sandbox
*******

.[perex]
Sandbox poskytuje bezpečnostní vrstvu, která vám dává kontrolu nad tím, jaké značky, PHP funkce, metody apod. mohou být v šablonách použity. Díky sandbox režimu můžete bezpečně spolupracovat s klientem nebo externím kodérem na tvorbě šablon, aniž byste se museli obávat, že dojde k narušení aplikace nebo nežádoucím operacím.

Jak to funguje? Jednoduše nadefinujeme, co všechno šabloně dovolíme. Přičemž v základu je všechno zakázané a my postupně povolujeme. Následujícím kódem umožníme autorovi šablony používat značky `{block}`, `{if}`, `{else}` a `{=}`, což je značka pro [vypsání proměnné nebo výrazu|tags#Vypisování] a všechny filtry:

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

$latte->setPolicy($policy);
```

Dále můžeme povolit jednotlivé funkce, metody nebo properties objektů:

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

Není to úžasné? Můžete na velmi nízké úrovni kontrolovat úplně všechno. Pokud se šablona pokusí zavolat nepovolenou funkci nebo přistoupit k nepovolené metodě nebo property, skončí to výjimkou `Latte\SecurityViolationException`.

Tvořit policy od bodu nula, kdy je zakázáno úplně vše, nemusí být pohodlné, proto můžete začít od bezpečného základu:

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

Bezpečný základ znamená, že jsou povoleny všechny standardní tagy kromě  `contentType`, `debugbreak`, `dump`, `extends`, `import`, `include`, `layout`, `php`, `sandbox`, `snippet`, `snippetArea`, `templatePrint`, `varPrint`, `widget`.
Jsou povoleny standardní filtry kromě `datastream`, `noescape` a `nocheck`. A nakonec je povolený přístup k metodám a properites objektu `$iterator`.

Pravidla se aplikují pro šablonu, kterou vložíme značkou [`{sandbox}` |tags#Vložení šablon]. Což je jakási obdoba `{include}`, která však zapíná bezpečný režim a také nepředává žádné proměnné:

```latte
{sandbox 'untrusted.latte'}
```

Tedy layout a jednotlivé stránky mohou nerušeně využívat všechny tagy a proměnné, pouze na šablonu `untrusted.latte` budou uplatněny restrikce.

Některé prohřešky, jako použití zakázaného tagu nebo filtru, se odhalí v době kompilace. Jiné, jako třeba volání nepovolených metod objektu, až za běhu.
Šablona také může obsahovat jakékoliv jiné chyby. Aby vám ze sandboxované šablony nemohla vyskočit výjimka, která naruší celé vykreslování, lze definovat vlastní [obslužný handler pro výjimky|develop#exception handler], který ji třeba zaloguje.

Pokud bychom chtěli sandbox režim zapnout přímo pro všechny šablony, jde to snadno:

```php
$latte->setSandboxMode();
```

Abyste měli jistotu, že uživatel do stránky nevloží PHP kód, který je sice syntakticky správný, ale zakázaný a způsobí PHP Compile Error, doporučujeme nechávat [šablony kontrolovat PHP linterem |develop#Kontrola vygenerovaného kódu]. Tuto funkčnost zapnete metodou `Engine::enablePhpLint()`. Jelikož ke kontrole potřebuje volat binárku PHP, cestu k ní předejte jako parametr:

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

Sandbox

Sandbox poskytuje bezpečnostní vrstvu, která vám dává kontrolu nad tím, jaké značky, PHP funkce, metody apod. mohou být v šablonách použity. Díky sandbox režimu můžete bezpečně spolupracovat s klientem nebo externím kodérem na tvorbě šablon, aniž byste se museli obávat, že dojde k narušení aplikace nebo nežádoucím operacím.

Jak to funguje? Jednoduše nadefinujeme, co všechno šabloně dovolíme. Přičemž v základu je všechno zakázané a my postupně povolujeme. Následujícím kódem umožníme autorovi šablony používat značky {block}, {if}, {else} a {=}, což je značka pro vypsání proměnné nebo výrazu a všechny filtry:

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

$latte->setPolicy($policy);

Dále můžeme povolit jednotlivé funkce, metody nebo properties objektů:

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

Není to úžasné? Můžete na velmi nízké úrovni kontrolovat úplně všechno. Pokud se šablona pokusí zavolat nepovolenou funkci nebo přistoupit k nepovolené metodě nebo property, skončí to výjimkou Latte\SecurityViolationException.

Tvořit policy od bodu nula, kdy je zakázáno úplně vše, nemusí být pohodlné, proto můžete začít od bezpečného základu:

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

Bezpečný základ znamená, že jsou povoleny všechny standardní tagy kromě contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint, widget. Jsou povoleny standardní filtry kromě datastream, noescape a nocheck. A nakonec je povolený přístup k metodám a properites objektu $iterator.

Pravidla se aplikují pro šablonu, kterou vložíme značkou {sandbox}. Což je jakási obdoba {include}, která však zapíná bezpečný režim a také nepředává žádné proměnné:

{sandbox 'untrusted.latte'}

Tedy layout a jednotlivé stránky mohou nerušeně využívat všechny tagy a proměnné, pouze na šablonu untrusted.latte budou uplatněny restrikce.

Některé prohřešky, jako použití zakázaného tagu nebo filtru, se odhalí v době kompilace. Jiné, jako třeba volání nepovolených metod objektu, až za běhu. Šablona také může obsahovat jakékoliv jiné chyby. Aby vám ze sandboxované šablony nemohla vyskočit výjimka, která naruší celé vykreslování, lze definovat vlastní obslužný handler pro výjimky, který ji třeba zaloguje.

Pokud bychom chtěli sandbox režim zapnout přímo pro všechny šablony, jde to snadno:

$latte->setSandboxMode();

Abyste měli jistotu, že uživatel do stránky nevloží PHP kód, který je sice syntakticky správný, ale zakázaný a způsobí PHP Compile Error, doporučujeme nechávat šablony kontrolovat PHP linterem. Tuto funkčnost zapnete metodou Engine::enablePhpLint(). Jelikož ke kontrole potřebuje volat binárku PHP, cestu k ní předejte jako parametr:

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