Güvenlikle ilişkili JavaScript hatalarını önleme

Adobe AIR 1.0 ve üstü

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.” Bu hatayı önlemek için, bu kodlama uygulamalarını takip edin.

Güvenlik ilişkili JavaScript hatalarının nedenleri

Belge load olayı tetiklendiğinde ve herhangi bir load olay işleyicisinden çıkıldığında, uygulama sanal alanında yürütülen kod, değerlendirme ve yürütme dizeleri içeren çoğu uygulamadan kısıtlanır. Güvenli olmayabilecek dizeleri değerlendiren ve yürüten aşağıdaki JavaScript ifade türlerinin kullanılmaya çalışılması JavaScript hataları oluşturur:

Uygulama içeriğini farklı bir sanal alana eşleme

Çoğu durumda, güvenlik ilişkili JavaScript hatalarını önlemek amacıyla bir uygulamayı yeniden yazabilir veya yeniden yapılandırabilirsiniz. Ancak, yeniden yazma veya yeniden yapılandırma olanaklı olmadığında uygulama içeriğini Uygulama içeriğini uygulama dışı sanal alana yükleme bölümünde anlatılan tekniği kullanarak farklı bir sanal alana yükleyebilirsiniz. Bu içeriğin AIR API'lerine de erişmesi gerekiyorsa, Sanal alan köprü arabirimini kurma bölümünde anlatıldığı biçimde bir sanal alan köprüsü oluşturabilirsiniz.

eval() işlevi

Uygulama sanal alanında, eval() işlevi yalnızca load olayı sayfasından önce veya load olay işleyicisi sırasında kullanılabilir. Sayfa yüklendikten sonra, eval() işlevine yapılan çağrılar kodu yürütmez. Ancak, aşağıdaki durumlarda eval() işlevinin kullanımını önlemek için kodunuzu yeniden yazabilirsiniz.

Nesneye özellikler atama

Özellik erişimcisi oluşturmak için dizeyi ayrıştırmak yerine:

eval("obj." + propName + " = " + val);

köşeli parantez açıklaması içeren access özellikleri:

obj[propName] = val;

Bağlamda var olan değişkenler içeren işlev oluşturma

İfadeleri aşağıdaki şekilde değiştirin:

function compile(var1, var2){ 
    eval("var fn = function(){ this."+var1+"(var2) }"); 
    return fn; 
}

şununla:

function compile(var1, var2){ 
    var self = this; 
    return function(){ self[var1](var2) }; 
}

Sınıf adını dize parametresi olarak kullanarak nesne oluşturma

Aşağıdaki kodla tanımlanan varsayımsal bir JavaScript sınıfı düşünün:

var CustomClass =  
    { 
        Utils: 
        { 
            Parser: function(){ alert('constructor') } 
        }, 
        Data:  
        { 
         
        } 
    }; 
var constructorClassName = "CustomClass.Utils.Parser";

Örnek oluşturmanın en basit yolu eval() işlevini kullanmaktır:

var myObj; 
eval('myObj=new ' + constructorClassName +'()')

Ancak, sınıf adının her bileşenini ayrıştırma ve köşeli parantez açıklaması kullanarak yeni nesne oluşturma yoluyla, eval() işlevinin çağrılmasını önleyebilirsiniz:

function getter(str) 
{ 
    var obj = window; 
    var names = str.split('.'); 
    for(var i=0;i<names.length;i++){ 
        if(typeof obj[names[i]]=='undefined'){ 
            var undefstring = names[0]; 
            for(var j=1;j<=i;j++) 
                undefstring+="."+names[j]; 
            throw new Error(undefstring+" is undefined"); 
        } 
        obj = obj[names[i]]; 
    } 
    return obj; 
}

Örneği oluşturmak için şunu kullanın:

try{ 
    var Parser = getter(constructorClassName); 
    var a = new Parser(); 
    }catch(e){ 
        alert(e); 
}

setTimeout() ve setInterval()

İşleyici işlevi olarak onaylanan dizeyi bir işlev başvurusu veya nesneyle değiştirin. Örneğin, ifadeyi şu şekilde değiştirin:

setTimeout("alert('Timeout')", 100);

şununla:

setTimeout(function(){alert('Timeout')}, 100); 

Veya işlev this nesnesinin çağıran tarafından ayarlanmasını gerektirdiğinde ifadeyi şu şekilde değiştirin:

this.appTimer = setInterval("obj.customFunction();", 100);

şununla:

var _self = this; 
this.appTimer = setInterval(function(){obj.customFunction.apply(_self);}, 100);

İşlev yapıcısı

new Function(param, body) çağrıları bir satır içi işlev bildirimiyle değiştirilebilir veya yalnızca sayfa load olayı işlenmeden önce kullanılabilir.

javascript: URL'ler

javascript kullanılarak linkte tanımlanan kod: Uygulama sanal alanında URL şeması yoksayılır. Güvenli olmayan JavaScript hatası oluşmadı. javascript aracılığıyla linkleri değiştirebilirsiniz: URL'ler, örneğin:

<a href="javascript:code()">Click Me</a>

şununla:

<a href="#" onclick="code()">Click Me</a>

innerHTML ve outerHTML ifadelerinde onevent nitelikleri aracılığıyla atanan olay geri çağrıları

Belge DOM'una öğe eklemek için innerHTML veya outerHTML kullandığınızda, ifadede atanan onclick veya onmouseover gibi olay geri çağrıları yoksayılır. Güvenlik hatası oluşmadı. Bunun yerine, addEventListener() yöntemini kullanarak yeni öğelere id niteliği atayabilir ve olay işleyici geri çağrı işlevlerini ayarlayabilirsiniz.

Örneğin, belgede şu şekilde bir hedef öğe belirlendiğinde:

<div id="container"></div>

İfadeleri şu şekilde değiştirin:

document.getElementById('container').innerHTML =  
    '<a href="#" onclick="code()">Click Me.</a>';

şununla:

document.getElementById('container').innerHTML = '<a href="#" id="smith">Click Me.</a>'; 
document.getElementById('smith').addEventListener("click", function() { code(); });

JavaScript dosyalarını uygulama yükleme dizini dışından yükleme

Uygulama sanal alanının dışından komut dosyaları yüklemeye izin verilmez. Güvenlik hatası oluşmadı. Uygulama sanal alanında çalışan tüm komut dosyaları uygulama dizinine yüklenmiş olmalıdır. Sayfada harici komut dosyaları kullanmak için, sayfayı farklı bir sanal alana eşlemelisiniz. Bkz. Uygulama içeriğini uygulama dışı sanal alana yükleme.

document.write() ve document.writeln()

Sayfa load olayı işlendikten sonra document.write() veya document.writeln() çağrıları yoksayılır. Güvenlik hatası oluşmadı. Alternatif olarak yeni bir dosya yükleyebilir veya DOM işleme tekniklerini kullanarak belge gövdesini değiştirebilirsiniz.

load olayından önce veya load olay işleyicisi sırasında senkronize XMLHttpRequests

load olayından önce veya load olay işleyicisi sırasında başlatılan senkronize XMLHttpRequest'ler herhangi bir içerik döndürmez. Senkronize olmayan XMLHttpRequest'ler başlatılabilir, ancak load olayının sonrasına kadar dönmez. load olayı işlendikten sonra senkronize XMLHttpRequest'ler normal davranır.

Dinamik olarak oluşturulan komut dosyası öğeleri

Dinamik olarak oluşturulan komut dosyası öğeleri, örneğin innerHTML ile veyadocument.createElement() yöntemiyle oluşturulduklarında yoksayılır.