Nette Documentation Preview

syntax
Sandbox
*******

.[perex]
Sandbox v Latte poskytuje robustní bezpečnostní vrstvu, která vám umožňuje precizně kontrolovat, jaké značky, PHP funkce, metody apod mohou být v šablonách použity. Díky tomuto mechanismu můžete bezpečně spolupracovat na tvorbě šablon s klienty nebo externími vývojáři, aniž byste riskovali narušení bezpečnosti vaší aplikace nebo nežádoucí operace.

Sandbox funguje na principu explicitního povolování. Ve výchozím stavu je vše zakázáno a vy postupně definujete, co šabloně dovolíte. Například takto povolíme používání značek `{block}`, `{if}`, `{else}` a `{=}` (pro [vypisování proměnných nebo výrazů|tags#Vypisování]) spolu se všemi filtry:

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

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

Dále můžeme selektivně povolit konkrétní funkce, metody objektů nebo jejich vlastnosti:

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

Tato úroveň granularity vám dává naprostou kontrolu nad tím, co může být v šablonách použito. Pokud se šablona pokusí o nepovolený úkon, Latte vyhodí výjimku `Latte\SecurityViolationException`.


Předpřipravená bezpečná politika
--------------------------------

Vytváření politiky od nuly může být časově náročné, proto Latte nabízí předpřipravenou bezpečnou výchozí politiku:

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

Tato politika povoluje všechny standardní značky kromě potenciálně nebezpečných jako `contentType`, `debugbreak`, `dump`, `extends`, `import`, `include`, `layout`, `php`, `sandbox`, `snippet`, `snippetArea`, `templatePrint`, `varPrint` a `widget`. Jsou povoleny všechny standardní filtry vyjma `datastream`, `noescape` a `nocheck`. Navíc je povolen přístup k metodám a vlastnostem objektu `$iterator`.


Aplikace sandboxu
-----------------

Pravidla sandboxu se aplikují na šablony vložené pomocí značky [`{sandbox}` |tags#Vložení šablon]. Ta funguje podobně jako `{include}`, ale aktivuje bezpečný režim a nepředává žádné proměnné:

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

Díky tomu mohou hlavní šablony (layout a jednotlivé stránky) využívat plnou funkcionalitu, zatímco na `untrusted.latte` se aplikují omezení.

Některá porušení pravidel, jako použití zakázané značky nebo filtru, se odhalí při kompilaci. Jiná, například volání nepovolených metod objektu, se detekují až za běhu.

Pro zachycení chyb v sandboxovaných šablonách můžete definovat vlastní [obslužný handler pro výjimky|develop#exception handler], který například zaloguje chybu bez narušení vykreslování celé stránky.


Globální aktivace sandboxu
--------------------------

Pokud chcete aplikovat sandbox režim na všechny šablony, stačí použít:

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


Dodatečná ochrana
-----------------

Pro ještě vyšší úroveň bezpečnosti doporučujeme zapnout kontrolu vygenerovaného PHP kódu pomocí PHP linteru. Tím se ujistíte, že uživatel nevložil do šablony syntakticky správný, ale zakázaný PHP kód, který by mohl způsobit PHP Compile Error. Aktivujte tuto funkci metodou `Engine::enablePhpLint()`:

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


Vlastní implementace Policy
---------------------------

Pokud potřebujete více flexibility při definování pravidel pro sandbox, můžete vytvořit vlastní třídu, která implementuje rozhraní `Latte\Policy` nebo rozšiřuje třídu `Latte\Sandbox\SecurityPolicy`. To vám umožní přesně definovat, jak se má kontrolovat povolení pro tagy, filtry, funkce, metody a vlastnosti.

Například, pokud chcete povolit všechny metody a vlastnosti objektů kromě několika specifických, můžete to snadno implementovat přepsáním metod `isMethodAllowed` a `isPropertyAllowed`:

```php
class MyPolicy extends Latte\Sandbox\SecurityPolicy
{
    public function isMethodAllowed(string $class, string $method): bool
    {
        // zakážeme pouze specifické metody $method ve třídě $class
        return ...
    }
}

$latte->setPolicy(new MyPolicy);
```

Tento přístup vám dává plnou kontrolu nad bezpečnostní politikou a umožňuje vám efektivně spravovat povolení pro velké množství objektů bez nutnosti definovat každou metodu a vlastnost jednotlivě.

Sandbox

Sandbox v Latte poskytuje robustní bezpečnostní vrstvu, která vám umožňuje precizně kontrolovat, jaké značky, PHP funkce, metody apod mohou být v šablonách použity. Díky tomuto mechanismu můžete bezpečně spolupracovat na tvorbě šablon s klienty nebo externími vývojáři, aniž byste riskovali narušení bezpečnosti vaší aplikace nebo nežádoucí operace.

Sandbox funguje na principu explicitního povolování. Ve výchozím stavu je vše zakázáno a vy postupně definujete, co šabloně dovolíte. Například takto povolíme používání značek {block}, {if}, {else} a {=} (pro vypisování proměnných nebo výrazů) spolu se všemi filtry:

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

$latte->setPolicy($policy);

Dále můžeme selektivně povolit konkrétní funkce, metody objektů nebo jejich vlastnosti:

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

Tato úroveň granularity vám dává naprostou kontrolu nad tím, co může být v šablonách použito. Pokud se šablona pokusí o nepovolený úkon, Latte vyhodí výjimku Latte\SecurityViolationException.

Předpřipravená bezpečná politika

Vytváření politiky od nuly může být časově náročné, proto Latte nabízí předpřipravenou bezpečnou výchozí politiku:

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

Tato politika povoluje všechny standardní značky kromě potenciálně nebezpečných jako contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint a widget. Jsou povoleny všechny standardní filtry vyjma datastream, noescape a nocheck. Navíc je povolen přístup k metodám a vlastnostem objektu $iterator.

Aplikace sandboxu

Pravidla sandboxu se aplikují na šablony vložené pomocí značky {sandbox}. Ta funguje podobně jako {include}, ale aktivuje bezpečný režim a nepředává žádné proměnné:

{sandbox 'untrusted.latte'}

Díky tomu mohou hlavní šablony (layout a jednotlivé stránky) využívat plnou funkcionalitu, zatímco na untrusted.latte se aplikují omezení.

Některá porušení pravidel, jako použití zakázané značky nebo filtru, se odhalí při kompilaci. Jiná, například volání nepovolených metod objektu, se detekují až za běhu.

Pro zachycení chyb v sandboxovaných šablonách můžete definovat vlastní obslužný handler pro výjimky, který například zaloguje chybu bez narušení vykreslování celé stránky.

Globální aktivace sandboxu

Pokud chcete aplikovat sandbox režim na všechny šablony, stačí použít:

$latte->setSandboxMode();

Dodatečná ochrana

Pro ještě vyšší úroveň bezpečnosti doporučujeme zapnout kontrolu vygenerovaného PHP kódu pomocí PHP linteru. Tím se ujistíte, že uživatel nevložil do šablony syntakticky správný, ale zakázaný PHP kód, který by mohl způsobit PHP Compile Error. Aktivujte tuto funkci metodou Engine::enablePhpLint():

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

Vlastní implementace Policy

Pokud potřebujete více flexibility při definování pravidel pro sandbox, můžete vytvořit vlastní třídu, která implementuje rozhraní Latte\Policy nebo rozšiřuje třídu Latte\Sandbox\SecurityPolicy. To vám umožní přesně definovat, jak se má kontrolovat povolení pro tagy, filtry, funkce, metody a vlastnosti.

Například, pokud chcete povolit všechny metody a vlastnosti objektů kromě několika specifických, můžete to snadno implementovat přepsáním metod isMethodAllowed a isPropertyAllowed:

class MyPolicy extends Latte\Sandbox\SecurityPolicy
{
    public function isMethodAllowed(string $class, string $method): bool
    {
        // zakážeme pouze specifické metody $method ve třídě $class
        return ...
    }
}

$latte->setPolicy(new MyPolicy);

Tento přístup vám dává plnou kontrolu nad bezpečnostní politikou a umožňuje vám efektivně spravovat povolení pro velké množství objektů bez nutnosti definovat každou metodu a vlastnost jednotlivě.