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();