Scatola di sabbia
Sandbox fornisce un livello di sicurezza che consente di controllare quali tag, funzioni PHP, metodi ecc. possono essere utilizzati nei template. Grazie alla modalità sandbox, è possibile collaborare in modo sicuro con un cliente o un codificatore esterno alla creazione di modelli, senza preoccuparsi di compromettere l'applicazione o di effettuare operazioni indesiderate.
Come funziona? Basta definire ciò che si vuole consentire nel modello. All'inizio, tutto è vietato e si concedono
gradualmente i permessi. Il codice seguente consente al template di utilizzare i tag {block}
, {if}
,
{else}
e {=}
(quest'ultimo è un tag per stampare
una variabile o un'espressione) e tutti i filtri:
$policy = new Latte\Sandbox\SecurityPolicy;
$policy->allowTags(['block', 'if', 'else', '=']);
$policy->allowFilters($policy::All);
$latte->setPolicy($policy);
Possiamo anche consentire l'accesso a funzioni, metodi o proprietà globali degli oggetti:
$policy->allowFunctions(['trim', 'strlen']);
$policy->allowMethods(Nette\Security\User::class, ['isLoggedIn', 'isAllowed']);
$policy->allowProperties(Nette\Database\Row::class, $policy::All);
Non è incredibile? Si può controllare tutto a un livello molto basso. Se il template tenta di chiamare una funzione non
autorizzata o di accedere a un metodo o a una proprietà non autorizzati, viene lanciata l'eccezione
Latte\SecurityViolationException
.
Creare politiche da zero, quando tutto è vietato, potrebbe non essere conveniente, quindi si può partire da una base sicura:
$policy = Latte\Sandbox\SecurityPolicy::createSafePolicy();
Questo significa che tutti i tag standard sono consentiti, tranne contentType
, debugbreak
,
dump
, extends
, import
, include
, layout
, php
,
sandbox
, snippet
, snippetArea
, templatePrint
, varPrint
,
widget
. Sono ammessi anche tutti i filtri standard, tranne datastream
, noescape
e
nocheck
. Infine, è consentito anche l'accesso ai metodi e alle proprietà dell'oggetto $iterator
.
Le regole si applicano al template che inseriamo con il nuovo tag {sandbox}
che è qualcosa di simile a , e . Che è
qualcosa di simile a {include}
, ma attiva la modalità sandbox e non passa alcuna variabile esterna:
{sandbox 'untrusted.latte'}
In questo modo, il layout e le singole pagine possono usare tutti i tag e le variabili come prima, le restrizioni saranno
applicate solo al template untrusted.latte
.
Alcune violazioni, come l'uso di un tag o di un filtro proibito, vengono rilevate in fase di compilazione. Altre, come la chiamata di metodi non consentiti di un oggetto, a tempo di esecuzione. Il template può contenere anche altri bug. Per evitare che venga lanciata un'eccezione dal template sandboxed, che interrompe l'intero rendering, è possibile definire un proprio gestore di eccezioni, che, ad esempio, si limita a registrarla.
Se si vuole attivare la modalità sandbox direttamente per tutti i template, è facile:
$latte->setSandboxMode();
Per assicurarsi che un utente non inserisca nella pagina codice PHP sintatticamente corretto ma vietato, causando un errore di compilazione PHP, si consiglia di far controllare i template dal linterno PHP. È possibile attivare questa funzionalità utilizzando il metodo Engine::enablePhpLint(). Poiché deve richiamare il binario PHP per il controllo, si deve passare il suo percorso come parametro:
$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');