Adobe AIR'de HTML güvenliği

Adobe AIR 1.0 ve üstü

Bu konu AIR HTML güvenlik yapısını ve HTML tabanlı uygulamalar oluşturmak ve HTML içeriğini SWF tabanlı uygulamalara güvenli bir şekilde entegre etmek için iframe'lerin, frame'lerin ve sanal alan köprüsünün nasıl kullanılacağını açıklar.

Çalışma zamanı, HTML ve JavaScript'teki olası güvenlik açıklarının üstesinden gelmek için kurallar uygular ve mekanizmalar sağlar. Uygulamanız temel olarak JavaScript'te yazılmış olduğunda veya HTML ve JavaScript içeriğini SWF tabanlı bir uygulamaya yüklediğinizde aynı kurallar uygulanır. Uygulama sanal alanında ve uygulama dışı güvenlik sanal alanındaki içeriğin farklı ayrıcalıkları vardır. Iframe'e veya frame'e içerik yüklenirken, çalışma zamanı, frame'deki veya iframe'deki içeriğin uygulama güvenlik sanal alanındaki içerikle güvenli biçimde iletişim kurmasını sağlayan güvenli bir sanal alan köprüsü mekanizması sağlar.

AIR SDK HTML içeriği oluşturmak için üç sınıf sağlar.

HTMLLoader sınıfı JavaScript kodu ve AIR API'leri arasında yakın entegrasyon sağlar.

StageWebView sınıfı HTML oluşturma sınıfıdır ve ana bilgisayar AIR uygulamasıyla sınırlı entegrasyonu vardır. StageWebView sınıfı tarafından yüklenen içerik asla uygulama güvenlik sanal alanına yerleştirilmez ve ana bilgisayar AIR uygulamasında veri veya çağrı işlevlerine erişemez. Masaüstü platformlarda StageWebView sınıfı Webkit'e dayalı olan ve HTMLLoader sınıfı tarafından kullanılan yerleşik AIR HTML motorunu kullanır. Mobil platformlarda StageWebView sınıfı işletim sistemi tarafından sağlanan HTML kontrolünü kullanır. Bu nedenle mobil platformlarda StageWebView sınıfı sistem web tarayıcısıyla aynı güvenlik kaygılarına ve açıklarına sahiptir.

TextField sınıfı HTML metninin dizelerini görüntüleyebilir. JavaScript yürütülemez ancak metin bağlantılar ve dışarıdan yüklenmiş görüntüler içerebilir.

Daha fazla bilgi için bkz. Güvenlikle ilişkili JavaScript hatalarını önleme.

HTML tabanlı uygulamanızın yapılandırılmasına genel bakış

Çerçeveler ve iframe'ler, AIR'de HTML içeriğinin düzenlenmesi için uygun bir yapı sağlar. Çerçeveler, hem veri kalıcılığını korumak hem de uzak içerikle güvenli bir şekilde çalışmak için yollar sağlar.

AIR'de HTML, normal, sayfa tabanlı düzenini koruduğundan, HTML içeriğinizin üst karesi farklı bir sayfaya “geçtiğinde” HTML ortamı tamamen yenilenir. Kareleri ve iframe'leri, tarayıcıda çalışan bir web uygulaması için yapacağınız gibi veri kalıcılığını korumak amacıyla kullanabilirsiniz. Üst karede ana uygulama nesnelerinizi tanımladığınızda, bu nesneler karenin yeni bir sayfaya geçmesine izin vermediğiniz sürece korunur. Uygulamanın geçici bölümlerini yüklemek ve görüntülemek için alt kareleri ve iframe'leri kullanın. (Veri kalıcılığını korumak için karelerin yanı sıra veya karelerin yerine kullanılabilecek çeşitli yollar mevcuttur. Bunlar tanımlama bilgilerini, yerel paylaşılan nesneleri, yerel dosya deposunu, şifrelenmiş dosya deposunu ve yerel veritabanı deposunu içerir.)

AIR'de HTML yürütülebilir kod ve veriler arasındaki normal, bulanık çizgisini koruduğundan, AIR HTML ortamının üst karesindeki içeriği uygulama sanal alanına yerleştirir. Sayfa load olayından sonra AIR, bir metin dizesini yürütülebilir bir nesneye çevirebilecek eval() gibi işlemleri sınırlar. Bu kısıtlama, uygulama uzak içerik yüklemediğinde bile uygulanır. HTML içeriğinin bu sınırlanmış işlemleri yürütebilmesi için, içeriği uygulama dışı bir sanal alana yerleştirmek üzere kareleri ve iframe'leri kullanmalısınız. (eval() işlevine dayanan bazı JavaScript uygulama çerçevelerinin kullanılması sırasında, içeriği sanal alanlı bir alt karede çalıştırmak gerekebilir.) Uygulama sanal alanındaki JavaScript kısıtlamalarının tam listesi için bkz. Farklı sanal alanlardaki içerik için kod kısıtlamaları.

AIR'de HTML uzak, büyük olasılıkla güvenli olmayan içerik yükleme özelliğini koruduğundan, AIR, bir etki alanındaki içeriğin farklı bir etki alanındaki içerikle etkileşime girmesini engelleyen aynı kaynak politikasını uygular. Uygulama içeriği ve farklı etki alanındaki içerik arasında etkileşime izin vermek için, üst ve alt kare arasında arabirim olarak görev yapacak bir köprü kurabilirsiniz.

Üst-alt sanal alan ilişkisini kurma

AIR, HTML kare ve iframe öğelerine sandboxRoot ve documentRoot niteliklerini ekler. Bu nitelikler, uygulama içeriğini başka bir etki alanından gelmiş gibi ele almanızı sağlar:

Nitelik

Açıklama

sandboxRoot

Kare içeriğinin yerleştirileceği sanal alan ve etki alanını belirlemek için kullanılacak URL. URL şemasının kullanması gereken file:, http: veya https:.

documentRoot

Kare içeriğinin yükleneceği kaynak URL. URL şemasının kullanması gereken file:, app: veya app-storage:.

Aşağıdaki örnek, uygulamanın sanal alan alt dizinine yüklenen içeriği uzak sanal alanda ve www.example.com etki alanında çalışacak biçimde eşler:

<iframe 
    src="ui.html"  
    sandboxRoot="http://www.example.com/local/"  
    documentRoot="app:/sandbox/"> 
</iframe>

Farklı sanal alanlarda veya etki alanlarında üst ve alt kareler arasında köprü kurma

AIR, her alt karenin window nesnesine childSandboxBridge ve parentSandboxBridge özelliklerini ekler. Bu özellikler, üst ve alt kare arasında arabirim olarak görev yapacak köprüleri tanımlamanızı sağlar. Her köprü bir yöne gider:

childSandboxBridgechildSandboxBridge özelliği alt karenin üst karedeki içeriğe bir arabirim göstermesini sağlar. Arabirim göstermek için childSandbox özelliğini alt karedeki bir işleme veya nesneye ayarlarsınız. Böylece nesneye veya işleve üst karedeki içerikten erişebilirsiniz. Aşağıdaki örnek, alt karede çalışan bir komut dosyasının bir işlev ve bir özellik içeren nesneyi üst öğesine nasıl gösterdiğini açıklar:

var interface = {}; 
interface.calculatePrice = function(){ 
    return .45 + 1.20; 
} 
interface.storeID = "abc" 
window.childSandboxBridge = interface;

Bu alt içerik, "child" öğenin id öğesi atanmış bir iframe içindeyse, karenin childSandboxBridge özelliğini okuyarak üst içerikten arabirime erişebilirsiniz:

var childInterface = document.getElementById("child").childSandboxBridge; 
air.trace(childInterface.calculatePrice()); //traces "1.65" 
air.trace(childInterface.storeID)); //traces "abc"

parentSandboxBridge parentSandboxBridge özelliği üst karenin alt karedeki içeriğe bir arabirim göstermesini sağlar. Arabirim göstermek için alt karenin parentSandbox özelliğini üst karedeki bir işleve veya bir nesneye ayarlarsınız. Böylece nesneye veya işleve alt karedeki içerikten erişebilirsiniz. Aşağıdaki örnek, üst karede çalışan bir komut dosyasının saklama işlevi içeren bir nesneyi alt öğeye nasıl gösterdiğini açıklar:

var interface = {}; 
interface.save = function(text){ 
    var saveFile = air.File("app-storage:/save.txt"); 
    //write text to file 
} 
document.getElementById("child").parentSandboxBridge = interface;

Alt karedeki içerik, bu arabirimi kullanarak save.txt adlı dosyaya metin kaydedebilir. Ancak, dosya sistemine başka bir erişimi olmayacaktır. Genellikle, uygulama içeriği diğer sanal alanlara olanaklı en dar arabirimi göstermelidir. Alt içerik saklama işlevini aşağıdaki şekilde çağırabilir:

var textToSave = "A string."; 
window.parentSandboxBridge.save(textToSave);

Alt içerik parentSandboxBridge nesnesinin bir özelliğini ayarlamaya çalıştığında, çalışma zamanı bir SecurityError istisnası atar. Üst içerik childSandboxBridge nesnesinin bir özelliğini ayarlamaya çalıştığında, çalışma zamanı bir SecurityError istisnası atar.

Farklı sanal alanlardaki içerik için kod kısıtlamaları

Bu Adobe AIR'de HTML güvenliği başlığında tartışıldığı gibi, çalışma zamanı HTML ve JavaScript'teki olası güvenlik açıklarının üstesinden gelebilmek için kurallar uygular ve mekanizmalar sağlar. Bu başlık, bu kısıtlamaları listeler. Kod, bu kısıtlanmış API'leri çağırmaya çalıştığında, çalışma zamanı “Uygulama güvenlik sanal alanındaki JavaScript kodu için Adobe AIR çalışma zamanı güvenlik ihlali” mesajını içeren bir hata verir.

Daha fazla bilgi için bkz. Güvenlikle ilişkili JavaScript hatalarını önleme.

JavaScript eval() işlevi ve benzer tekniklerin kullanımındaki kısıtlamalar

Uygulama güvenlik sanal alanındaki HTML içeriği için, kod yüklendiken sonra (body öğesinin onload olayı gönderildikten ve onload işleyici işlevinin yürütülmesi tamamlandıktan sonra) dizeleri dinamik olarak yürütülebilir koda dönüştürebilen API'lerin kullanımı için sınırlamalar mevcuttur. Bunun amacı, uygulamanın yanlışlıkla uygulama dışı kaynaklardan (güvenli olmayabilecek ağ etki alanları gibi) kod yerleştirmesini (ve yürütmesini) engellemektir.

Örneğin, uygulamanız DOM öğesinin innerHTML özelliğine yazmak için uzak bir kaynaktan dize verileri kullanıyorsa, dize güvenli olmayan işlemler gerçekleştirebilecek yürütülebilir (JavaScript) kod içerebilir. Ancak, içerik yüklenirken uzak dizelerin DOM'a eklenme riski yoktur.

JavaScript eval() işlevinin kullanımında bir kısıtlama vardır. Uygulama sanal alanındaki kod yüklendikten ve onload olay işleyicisindeki işlemeden sonra eval() işlevini sınırlı biçimde kullanabilirsiniz. Aşağıdaki kurallar, kodun uygulama güvenlik sanal alanından yüklenmesinden sonraeval() işlevinin kullanımı için geçerlidir:

  • Değişmez içeren ifadeler izinli. Örneğin:

    eval("null"); 
    eval("3 + .14"); 
    eval("'foo'");
  • Aşağıdaki gibi nesne değişmezleri izinlidir:

    { prop1: val1, prop2: val2 }
  • Aşağıdaki gibi nesne değişmezi ayarlayıcı/alıcıları izinli değildir:

    { get prop1() { ... }, set prop1(v) { ... } }
  • Aşağıdaki gibi dizi değişmezleri izinlidir:

    [ val1, val2, val3 ]
  • Aşağıdaki gibi özellik okumaları içeren ifadeler izinli değildir:

    a.b.c
  • İşlev başlatma izinli değil.

  • İşlev tanımları izinli değil.

  • Özellik ayarlama izinli değil.

  • İşlev değişmezleri izinli değil.

Ancak, kod yüklenirken, onload olayından önce ve onload olay işleyici işlevinin yürütülmesi sırasında bu kısıtlamalar uygulama güvenlik sanal alanındaki içeriğe uygulanmaz.

Örneğin, kod yüklendikten sonra istisna atan çalışma zamanı aşağıdaki kodla sonuçlanır:

eval("alert(44)"); 
eval("myFunction(44)"); 
eval("NativeApplication.applicationID");

Örneğin eval() işlevini çağırma sırasında yapılan gibi dinamik olarak oluşturulan kod, uygulama sanal alanında izinliyse bir güvenlik riski ortaya çıkarır. Örneğin, bir uygulama yanlışlıkla ağ etki alanından yüklenmiş bir dizeyi yürütebilir ve bu dize kötü amaçlı bir kod içerebilir. Örneğin, bu kod kullanıcının bilgisayarındaki dosyaları değiştiren veya silen bir kod olabilir. Veya yerel dosyanın içeriğini güvenilir olmayan bir ağ etki alanına bildiren bir kod olabilir.

Dinamik kod oluşturma yolları şunlardır:

  • eval() işlevini çağırma.

  • Uygulama dizininin dışındaki bir komut dosyasını yükleyen komut dosyası etiketleri eklemek için innerHTML özelliklerini veya DOM işlevlerini kullanma.

  • Satır içi kod içeren komut dosyası etikeleri eklemek için innerHTML özelliklerini veya DOM işlevlerini kullanma (src niteliği yoluyla komut dosyası yüklemek yerine).

  • Uygulama dizininin dışıda yer alan bir JavaScript dosyası yüklemek üzere script etiketleri için src niteliğini ayarlama.

  • Javascript URL şemasını kullama (href="javascript:alert('Test')" için olduğu gibi).

  • İlk parametre (işlevin senkronize olmayan bir şekilde çalışacağını tanımlayan) işlev adı (setTimeout('x = 4', 1000) gibi) yerine bir dize (değerlendirilecek) olduğunda setInterval() veya setTimout() işlevini kullanma.

  • document.write() veya document.writeln() çağırma.

Uygulama güvenlik sanal alanındaki kod, içerik yüklenirken yalnızca bu yöntemleri kullanabilir.

Bu kısıtlamalar, JSON nesne değişmezleriyle eval() işlevinin kullanılmasını engellemez. Bu, uygulama içeriğinizin JSON JavaScript kitaplığıyla çalışmasını sağlar. Ancak, aşırı yüklü JSON kodu kullanımınız kısıtlanmıştır (olay işleyicileriyle).

Diğer Ajax çerçeveleri ve JavaScript kod kitaplıkları için, çerçevedeki veya kitaplıktaki kodun dinamik olarak oluşturulan kodlara ilişkin bu kısıtlamalarla çalışıp çalışmadığını kontrol edin. Çalışmıyorsa, uygulama dışı güvenlik sanal alanına çerçeveyi veya kitaplığı kullanan içerik dahil edin. Ayrıntılar için bkz. AIR uygulamasının içindeki JavaScript'in sınırlılıkları ve Uygulama içeriği ve uygulama dışı içerik arasında komut dosyası oluşturma. Adobe, http://www.adobe.com/products/air/develop/ajax/features/ linklerinde uygulama güvenlik sanal alanını desteklemek için bilinen Ajax çerçevelerinin listesini tutar.

Uygulama güvenlik sanal alanındaki içerikten farklı olarak, uygulama dışı bir güvenlik sanal alanında yer alan JavaScript içeriği, dinamik olarak oluşturulan kodu yürütmek için her zaman eval() işlevini çağırabilir.

AIR API'lerine erişim sınırlamaları (uygulama dışı sanal alanlar için)

Uygulama dışı sanal alandaki JavaScript kodunun window.runtime nesnesine erişimi yoktur, ve aynı şekilde bu kod AIR API'lerini yürütemez. Uygulama dışı güvenlik sanal alanındaki içerik aşağıdaki kodu çağırdığında, uygulama bir TypeError istisnası atar:

try { 
    window.runtime.flash.system.NativeApplication.nativeApplication.exit(); 
}  
catch (e)  
{ 
    alert(e); 
}

Uygulama dışı sanal alandaki içerik window.runtime nesnesini tanımadığından, istisna TypeError (tanımlanmamış değer) türündedir, bu nedenle tanımlanmamış bir değer olarak görülür.

Uygulama dışı sanal alandaki içeriğe komut dosyası köprüsünü kullanarak çalışma zamanı işlevi gösterebilirsiniz. Ayrıntılar için bkz. Uygulama içeriği ve uygulama dışı içerik arasında komut dosyası oluşturma.

XMLHttpRequest çağrılarının kullanımına ilişkin kısıtlamalar

Uygulama güvenlik sanal alanındaki HTML içeriği, HTML içeriği yüklenirken ve onLoad olayı sırasında uygulama sanal alanının dışından veri yüklemek için senkronize XMLHttpRequest yöntemlerini kullanamaz.

Varsayılan olarak, uygulama dışı güvenlik sanal alanlarındaki HTML içeriği, isteği çağıran etki alanı dışındaki etki alanlarından veri yüklemek üzere JavaScript XMLHttpRequest nesnesini kullanmak için izne sahip değildir. Bir frame veya iframe etiketi allowcrosscomainxhr niteliğini dahil edebilir. Bu niteliği herhangi bir null olmayan değere ayarlamak, frame veya iframe'deki içeriğin isteği çağıran kodun etki alanından başka etki alanlarından veri yüklemek için JavaScript XMLHttpRequest nesnesini kullanmasına izin verir.

<iframe id="UI" 
    src="http://example.com/ui.html" 
    sandboxRoot="http://example.com/" 
    allowcrossDomainxhr="true" 
    documentRoot="app:/"> 
</iframe>

Daha fazla bilgi için bkz. Farklı etki alanlarındaki içerikler arasında komut dosyası oluşturma.

CSS, kare, iframe ve img öğelerinin yüklenmesine ilişkin kısıtlamalar (uygulama dışı sanal alanlardaki içerik için)

Uzak (ağ) güvenlik sanal alanlarındaki HTML içeriği uzak sanal alanlardan (ağ URL'lerinden) yalnızca frame, iframe ve img içeriği yükleyebilir.

Dosya sistemiyle yerel, ağ iletişimiyle yerel veya yerel-güvenilir sanal alanlardaki HTML içeriği yerel sanal alanlardan (uygulamadan veya uzak sanal alanlardan değil) yalnızca frame, iframe ve img içeriğini okuyabilir.

JavaScript window.open() yönteminin çağrılmasına ilişkin kısıtlamalar

JavaScript window.open() yöntemine çağrı yoluyla oluşturulan bir pencere, uygulama dışı güvenlik sanal alanından içerik görüntülediğinde, pencere başlığı ana (başlatılan) pencerenin başlığıyla başlar ve iki nokta karakteriyle devam eder. Pencere başlığının bu bölümünü ekranın dışına taşımak için kodu kullanamazsınız.

Uygulama dışı güvenlik sanal alanlarındaki içerik, kullanıcı fare veya klavye etkileşimiyle tetiklenen bir olaya yanıt olarak yalnızca JavaScript window.open() yöntemini başarıyla çağırabilir. Bu, uygulama dışı içeriğin aldatıcı biçimde kullanılabilecek pencereler oluşturmasını engeller (örneğin kimlik avı saldırıları). Ayrıca, fare veya klavye olayı için olay işleyici, window.open() yöntemini gecikmeden sonra yürütülmek üzere ayarlayamaz (örneğin setTimeout() işlevini çağırarak).

Uzak sanal alanlardaki (ağ) içerik, içeriği uzak ağ sanal alanlarında açmak için yalnızca window.open() yöntemini kullanabilir. İçeriği uygulamadan veya yerel sanal alanlardan açmak için window.open() yöntemini kullanamaz.

Dosya sistemiyle yerel, ağ iletişimiyle yerel veya yerel-güvenli sanal alanlardaki (bkz. Güvenlik sanal alanları) içerik, yerel sanal alanlarda içerik açmak için yalnızca window.open() yöntemini kullanabilir. İçeriği uygulamadan veya uzak sanal alanlardan açmak için window.open() yöntemini kullanamaz.

Kısıtlanmış kodu çağırmada hata

Bu güvenlik kısıtlamaları nedeniyle sanal alanda kullanımı kısıtlanmış olan kodu çağırdığınızda çalıştırma zamanı bir JavaScript hatası gönderir: "Uygulama güvenlik sanal alanında JavaScript koduna ilişkin Adobe AIR çalıştırma zamanı güvenlik ihlali."

Daha fazla bilgi için bkz. Güvenlikle ilişkili JavaScript hatalarını önleme.

Dizeden HTML içeriği yükleme sırasında sanal alan koruması

HTMLLoader sınıfının loadString() yöntemi, çalışma zamanında HTML içeriği oluşturmanızı sağlar. Ancak, HTML içeriği olarak kullandığınız veriler güvenli olmayan bir Internet kaynağından yüklendiyse, bozuk olabilir. Bu nedenle, loadString() yöntemi kullanılarak oluşturulan HTML varsayılan olarak uygulama sanal alanına yerleştirilmez ve AIR API'lerine erişimi yoktur. Ancak, loadString() yöntemi kullanılarak oluşturulan HTML'yi uygulama sanal alanına yerleştirmek için HTMLLoader nesnesinin placeLoadStringContentInApplicationSandbox özelliğini true olarak ayarlayabilirsiniz. Daha fazla bilgi için bkz. Bir dizeden HTML içeriğini yükleme.