Chrome'un uzantı sistemi, oldukça katı bir varsayılan İçerik Güvenliği Politikası (İGP) uygular.
Politika kısıtlamaları basittir: Komut dosyası satır dışına, ayrı JavaScript dosyalarına taşınmalıdır, satır içi etkinlik işleyicileri addEventListener
kullanacak şekilde dönüştürülmelidir ve eval()
devre dışı bırakılmalıdır. Chrome Uygulamaları'nın daha da sıkı bir politikası vardır ve
özellikleri hakkında daha fazla bilgi edinin.
Bununla birlikte, çeşitli kütüphanelerin eval()
ve eval
benzeri yapıları kullandığının farkındayız:
Performans optimizasyonu ve ifade kolaylığı için new Function()
. Şablon oluşturma kitaplıkları
bu uygulama tarzına çok açıktır. Bazıları (Angular.js gibi) İGP'yi destekler.
Çoğu popüler çerçeve, henüz deneme sürümüyle uyumlu olmayan bir mekanizmaya
uzantıları eval
daha az dünya. Bu nedenle, bu işlev için desteğin kaldırılması geliştiriciler için beklenenden daha sorunlu oldu.
Bu dokümanda, bu kitaplıkları güvenlikten ödün vermeden projelerinize dahil etmek için güvenli bir mekanizma olarak korumalı alan kullanımı tanıtılmaktadır. Özetlemek amacıyla, bu makale boyunca uzantılar terimini kullanacağız ancak bu kavram uygulamalar için de geçerlidir.
Korumalı alan neden gerekli?
eval
, yürüttüğü bir kod uzantıdaki her şeye erişebildiğinden bu uzantı içinde tehlikeli bir durum
eklentisinin yüksek izinli ortamını yönetebilirsiniz. Kullanıcıların güvenliğini ve gizliliğini ciddi şekilde etkileyebilecek çok sayıda güçlü chrome.*
API mevcuttur. Basit veri sızıntıları, endişelerimiz arasında en az önemli olanıdır.
Sunulan çözüm, eval
ürününün
genişletmenin verileri veya uzantının yüksek değerli API'leri. Veri yok, API yok, sorun yok.
Bunu, uzantı paketindeki belirli HTML dosyalarını korumalı alan olarak listelememiz sayesinde yapıyoruz.
Korumalı alana alınmış bir sayfa yüklendiğinde benzersiz bir kaynağa taşınır ve reddedilir
chrome.*
API'lerine erişim. Korumalı alana alınmış bu sayfayı bir iframe
aracılığıyla uzantımıza yüklersek
veya bu iletiler üzerinde bir şekilde işlem yapmasına izin verebilir ve
bunun bize geri bildirimlerinizi iletmesini bekleyebilir.
yardımcı olur. Bu basit mesajlaşma mekanizması, uzantımızın iş akışına eval
tarafından yönlendirilen kodu güvenli bir şekilde dahil etmek için ihtiyacımız olan her şeyi bize sağlar.
Korumalı alan oluşturma ve kullanma.
Hemen koda dalmak istiyorsanız lütfen korumalı alan örnek uzantısını indirin ve işe başlayın. Bu, Handlebars şablon kitaplığının üzerine inşa edilmiş küçük bir mesajlaşma API'sinin çalışan bir örneğidir ve çalışmaya başlamak için ihtiyacınız olan her şeyi sağlar. Konuyu biraz daha ayrıntılı bir şekilde öğrenmek isteyenler için bu örneği birlikte inceleyelim.
Manifest dosyasında dosyaları listeleme
Korumalı alan içinde çalışması gereken her dosya,
sandbox
mülk. Bu kritik bir adımdır ve kolayca unutulabilir. Lütfen korumalı alan dosyanızı manifest dosyasında listelediğinizden emin olun. Bu örnekte, "sandbox.html" olarak adlandırılan dosyayı korumalı alana alıyoruz. Manifest girişi aşağıdaki gibi görünür:
{
...,
"sandbox": {
"pages": ["sandbox.html"]
},
...
}
Korumalı alana alınan dosyayı yükle
Korumalı alan dosyası ile ilginç bir şey yapmak için dosyayı, uzantının kodu tarafından erişilebileceği bir bağlamda yüklememiz gerekir. Burada sandbox.html, iframe
aracılığıyla uzantının Etkinlik Sayfası'na (eventpage.html) yüklenir. eventpage.js kod içerir
iframe
ve contentWindow
üzerinde postMessage
yöntemini yürütüyoruz. Mesaj bir nesnedir
Şu iki özellik içeren: context
ve command
. Birazdan her ikisine de değineceğiz.
chrome.browserAction.onClicked.addListener(function() {
var iframe = document.getElementById('theFrame');
var message = {
command: 'render',
context: {thing: 'world'}
};
iframe.contentWindow.postMessage(message, '*');
});
postMessage
API hakkında genel bilgi edinmek için MDN'deki postMessage
belgelerine göz atın. Oldukça kapsamlı ve okumaya değer. Özellikle, verilerin yalnızca seri hale getirilebilmesi halinde karşılıklı aktarılabileceğini unutmayın. Örneğin, işlevler herhangi bir koşula tabi değildir.Tehlikeli bir şey yap
sandbox.html
yüklendiğinde Handlebars kitaplığı yüklenir ve Handlebars'ın önerdiği şekilde satır içi bir şablon oluşturulup derlenir:
<script src="handlebars-1.0.0.beta.6.js"></script>
<script id="hello-world-template" type="text/x-handlebars-template">
<div class="entry">
<h1>Hello, !</h1>
</div>
</script>
<script>
var templates = [];
var source = document.getElementById('hello-world-template').innerHTML;
templates['hello'] = Handlebars.compile(source);
</script>
Bu işlem başarısız olmaz! Handlebars.compile
, new Function
işlevini kullansa da çalışır.
tam olarak beklendiği gibi olduğunda templates['hello']
içinde derlenmiş bir şablon elde ederiz.
Sonucu geri gönderme
Etkinlik sayfasından komutları kabul eden bir mesaj dinleyici ayarlayarak bu şablonu kullanıma sunacağız. Yapılması gerekenleri belirlemek için iletilen command
belgesini kullanırız (
yalnızca görüntüleme değil, şablonlar hazırlıyor mu? Belki bunları belirli bir
şekilde?) ve context
, oluşturma için doğrudan şablona aktarılır. Oluşturulan HTML
etkinlik sayfasına geri gönderilir. Böylece, uzantı daha sonra faydalı bir işlem yapabilir:
<script>
window.addEventListener('message', function(event) {
var command = event.data.command;
var name = event.data.name || 'hello';
switch(command) {
case 'render':
event.source.postMessage({
name: name,
html: templates[name](event.data.context)
}, event.origin);
break;
// case 'somethingElse':
// ...
}
});
</script>
Etkinlik sayfasına dönersek bu mesajı alıp html
ile ilgi çekici bir şey yapacağız.
iletilmiş verilerdir. Bu durumda, Masaüstü Bildirimi üzerinden bunu tekrarlayacağız, ancak
bu HTML, uzantının kullanıcı arayüzünün bir parçası olarak güvenli bir şekilde kullanılabilir. innerHTML
üzerinden ekleme yapmak önemli bir güvenlik riski oluşturmaz. Çünkü bazı akıllı saldırılar yoluyla korumalı alandaki kodda tam bir güvenlik ihlali olsa bile yüksek izinli uzantı bağlamına tehlikeli komut dosyası veya eklenti içeriği eklenemez.
Bu mekanizma, şablon oluşturmayı kolaylaştırır ancak şablon oluşturmayla sınırlı değildir. Katı bir İçerik Güvenliği Politikası altında kutudan çıkar çıkmaz çalışmayan tüm kodlar korumalı alana yerleştirilebilir. Aslında, programınızın her bir parçasını düzgün şekilde yürütülmesi için gereken en küçük ayrıcalıklar grubuyla kısıtlamak amacıyla, uzantılarınızın doğru şekilde çalışacak bileşenlerini korumalı alana yerleştirmek genellikle yararlıdır. Google'dan Güvenli Web Uygulamaları ve Chrome Uzantıları Yazma sunumu I/O 2012, bu tekniklerin nasıl kullanıldığına dair iyi örnekler veriyor. 2012'de bu teknikle ilgili gerekir.