Sandbox
A Sandbox egy olyan biztonsági réteget biztosít, amely lehetővé teszi, hogy ellenőrizze, mely címkék, PHP-funkciók, metódusok stb. használhatók a sablonokban. A sandbox módnak köszönhetően biztonságosan együttműködhet egy ügyféllel vagy külső kódolóval a sablonok létrehozásában anélkül, hogy aggódnia kellene az alkalmazás veszélyeztetése vagy nem kívánt műveletek miatt.
Hogyan működik? Egyszerűen meghatározzuk, hogy mit szeretnénk engedélyezni a sablonban. Kezdetben minden tiltott, és
fokozatosan adjuk meg az engedélyeket. A következő kód engedélyezi a sablon számára a {block}
,
{if}
, {else}
és {=}
címkék (ez utóbbi egy változó
vagy kifejezés nyomtatására szolgáló címke) és az összes szűrő használatát:
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$latte->setPolicy($policy);
Az objektumok globális függvényeihez, módszereihez vagy tulajdonságaihoz való hozzáférést is engedélyezhetjük:
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
Hát nem csodálatos? Nagyon alacsony szinten mindent irányíthatsz. Ha a sablon megpróbál meghívni egy nem engedélyezett
függvényt vagy hozzáférni egy nem engedélyezett metódushoz vagy tulajdonsághoz, akkor kivételt dob
Latte\SecurityViolationException
.
A házirendek létrehozása a semmiből, amikor minden tiltott, nem biztos, hogy kényelmes, így egy biztonságos alapról indulhat:
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
Ez azt jelenti, hogy minden szabványos címke engedélyezett, kivéve a contentType
, debugbreak
,
dump
, extends
, import
, include
, layout
, php
,
sandbox
, snippet
, snippetArea
, templatePrint
, varPrint
,
widget
. Az összes szabványos szűrő is megengedett, kivéve a datastream
, noescape
és
nocheck
. Végül a $iterator
objektum metódusaihoz és tulajdonságaihoz való hozzáférés is
engedélyezett.
A szabályok az új sablonra vonatkoznak, amelyet az új {sandbox}
címkével. Ami egy olyasmi, mint a {include}
, de bekapcsolja a sandbox módot, és nem ad át külső
változókat sem:
{sandbox 'untrusted.latte'}
Így az elrendezés és az egyes oldalak ugyanúgy használhatják az összes taget és változót, mint korábban, a
korlátozások csak a sablonra vonatkoznak untrusted.latte
.
Egyes szabálysértések, például tiltott címkék vagy szűrők használata, már a fordításkor észlelésre kerülnek. Mások, mint például egy objektum nem engedélyezett metódusainak meghívása, futásidőben. A sablon bármilyen más hibát is tartalmazhat. Annak érdekében, hogy a sandboxolt sablonból ne dobjon ki kivételt, ami megzavarja a teljes renderelést, definiálhat saját kivételkezelőt, amely például csak naplózza azt.
Ha közvetlenül az összes sablonra szeretnénk bekapcsolni a sandbox módot, az egyszerű:
$latte->setSandboxMode();
Annak biztosítása érdekében, hogy a felhasználó ne illesszen be olyan PHP-kódot az oldalba, amely szintaktikailag helyes, de tiltott, és PHP-fordítási hibát okoz, javasoljuk, hogy a sablonokat a PHP-interrel ellenőriztesse. Ezt a funkciót az Engine::enablePhpLint() metódus segítségével aktiválhatja. Mivel az ellenőrzéshez meg kell hívnia a PHP binárisát, adja meg annak elérési útvonalát paraméterként:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');