Sandbox

Latte'nin doğrudan kaputun altında zırhlı bir kalesi vardır. Buna sandbox modu denir ve güvenilmeyen kaynaklardan gelen şablonları kullanan uygulamaları koruyan önemli bir özelliktir. Örneğin, kullanıcıların kendileri tarafından düzenlendiklerinde.

Sandbox modu, kumun kutudan çıkmamasını sağlar. Böylece etiketlere, filtrelere, işlevlere, yöntemlere vb. sınırlı erişim sağlar. Nasıl çalışır? Basitçe şablonda neye izin vermek istediğimizi tanımlarız. Başlangıçta her şey yasaktır ve kademeli olarak izinler veririz:

Aşağıdaki kod, şablonun {block}, {if}, {else} ve {=} etiketlerini (ikincisi bir değişken veya ifadeyi yazdırmak için kullanılan bir etikettir) ve tüm filtreleri kullanmasını sağlar:

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

$latte->setPolicy($policy);

Nesnelerin global fonksiyonlarına, metotlarına veya özelliklerine erişime de izin verebiliriz:

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

İnanılmaz değil mi? Her şeyi çok düşük bir seviyede kontrol edebilirsiniz. Şablon yetkisiz bir işlevi çağırmaya veya yetkisiz bir yönteme ya da özelliğe erişmeye çalışırsa Latte\SecurityViolationException istisnasını atar.

Her şey yasakken sıfırdan politika oluşturmak uygun olmayabilir, bu nedenle güvenli bir temelden başlayabilirsiniz:

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

Bu, contentType, debugbreak, dump, extends, import, include, layout, php, sandbox, snippet, snippetArea, templatePrint, varPrint, widget hariç tüm standart etiketlere izin verildiği anlamına gelir. datastream, noescape ve nocheck hariç tüm standart filtrelere de izin verilmektedir. Son olarak, $iterator nesnesinin yöntemlerine ve özelliklerine erişime de izin verilir.

Kurallar, yeni şablonla birlikte eklediğimiz şablon için geçerlidir {sandbox} etiketi. Bu {include} gibi bir şeydir, ancak sandbox modunu açar ve ayrıca herhangi bir harici değişken geçmez:

{sandbox 'untrusted.latte'}

Böylece, düzen ve tek tek sayfalar daha önce olduğu gibi tüm etiketleri ve değişkenleri kullanabilir, kısıtlamalar yalnızca untrusted.latte şablonuna uygulanacaktır.

Yasak etiket veya filtre kullanımı gibi bazı ihlaller derleme zamanında tespit edilir. Bir nesnenin izin verilmeyen yöntemlerinin çağrılması gibi diğerleri ise çalışma zamanında tespit edilir. Şablon başka hatalar da içerebilir. Sandbox'lı şablondan bir istisnanın fırlatılmasını önlemek için, örneğin sadece günlüğe kaydeden kendi istisna işleyicinizi tanımlayabilirsiniz.

Tüm şablonlar için doğrudan sandbox modunu açmak istiyorsak, bu çok kolay:

$latte->setSandboxMode();