Errori JavaScript relativi alla sicurezza da evitare

Adobe AIR 1.0 e versioni successive

Se chiamate un codice che per ragioni di sicurezza ha limitazioni d'uso in una sandbox, il runtime invia l'errore JavaScript “Adobe AIR runtime security violation for JavaScript code in the application security sandbox” (Violazione della sicurezza di Adobe AIR in fase di runtime per il codice JavaScript nella sandbox dell'applicazione). Per evitare questo errore, attenetevi alle seguenti pratiche di programmazione.

Cause degli errori JavaScript relativi alla sicurezza

Il codice eseguito nella sandbox dell'applicazione ha limitazioni per quanto riguarda gran parte delle operazioni che comportano la valutazione e l'esecuzione di stringhe dopo l'attivazione dell'evento load per il documento e dopo la chiusura di tutti i gestori di eventi load . Il tentativo di usare i seguenti tipi di istruzioni JavaScript che consentono di valutare ed eseguire stringhe potenzialmente non sicure provoca errori JavaScript:

Mappatura del contenuto dell'applicazione su una sandbox diversa

Nella maggior parte delle situazioni, potete riscrivere o cambiare la struttura di un'applicazione per evitare errori JavaScript di sicurezza. Tuttavia, quando non è possibile riscrivere o cambiare la struttura, potete caricare il contenuto dell'applicazione in una sandbox diversa usando la tecnica descritta in Caricamento del contenuto delle applicazioni in una sandbox non applicazione . Se il contenuto deve anche accedere alle API di AIR, potete creare un bridge sandbox, come descritto in Impostazione dell'interfaccia per un bridge sandbox .

Funzione eval()

Nella sandbox dell'applicazione, è possibile usare la funzione eval() solo prima dell'evento load della pagina o durante la gestione di eventi load . Al termine del caricamento della pagina, le chiamate a eval() non eseguiranno il codice. Tuttavia, nei seguenti casi potete riscrivere il codice per evitare l'uso della funzione eval() .

Assegnazione di proprietà a un oggetto

Invece di analizzare una stringa per creare la proprietà accessor:

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

proprietà di accesso con la notazione tra parentesi:

obj[propName] = val;

Creazione di una funzione con variabili disponibili nel contesto

Sostituite le istruzioni simili alle seguenti:

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

con:

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

Creazione di un oggetto usando il nome della classe come parametro stringa

Prendete in considerazione un'ipotetica classe JavaScript definita dal seguente codice:

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

Il modo più semplice per creare un'istanza sarebbe quello di usare la funzione eval() :

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

Tuttavia, potete evitare la chiamata a eval() analizzando ciascun componente del nome della classe e creando il nuovo oggetto con la notazione tra parentesi quadre:

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; 
}

Per creare l'istanza, usate:

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

setTimeout() e setInterval()

Sostituite la stringa passata come funzione del gestore con un riferimento alla funzione o un oggetto. Ad esempio, sostituite un'istruzione del tipo:

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

con:

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

In alternativa, quando la funzione richiede l'impostazione dell'oggetto this da parte del chiamante, sostituite un'istruzione del tipo:

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

con la seguente:

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

Funzione di costruzione Function

Le chiamate a new Function(param, body) possono essere sostituite con una dichiarazione di funzione in linea oppure possono essere usate solo prima della gestione dell'evento load della pagina.

URL javaScript:

Il codice definito in un collegamento con lo schema javascript: URL viene ignorato nella sandbox dell'applicazione. Non viene generato alcun errore JavaScript. Potete sostituire i collegamenti usando gli URL javascript:, ad esempio:

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

con:

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

Callback di eventi assegnati tramite gli attributi onevent nelle istruzioni innerHTML e outerHTML

Quando usate innerHTML o outerHTML per aggiungere elementi a un modello DOM di un documento, tutti i callback degli eventi assegnati all'interno dell'istruzione, ad esempio onclick o onmouseover , vengono ignorati. Non vengono generati errori di protezione. Al contrario, potete assegnare un attributo id ai nuovi elementi e impostare le funzioni di callback del gestore eventi usando il metodo addEventListener() .

Ad esempio, dopo avere prefissato un elemento target in un documento, quale:

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

Sostituite le istruzioni simili a:

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

con:

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

Caricamento di file JavaScript da un percorso esterno alla directory di installazione dell'applicazione

Il caricamento di file script da un percorso esterno alla sandbox dell'applicazione non è consentito. Non vengono generati errori di protezione. Tutti i file script in esecuzione nella sandbox dell'applicazione devono essere installati nella directory dell'applicazione. Per usare script esterni in una pagina, dovete mappare la pagina su una diversa sandbox. Consultate Caricamento del contenuto delle applicazioni in una sandbox non applicazione .

document.write() e document.writeln()

Le chiamate a document.write() o document.writeln() vengono ignorate dopo che l'evento load della pagina è stato gestito. Non vengono generati errori di protezione. In alternativa, potete caricare un nuovo file o sostituire il corpo del documento usando le tecniche di manipolazione DOM.

Richieste XMLHttpRequests sincrone antecedenti all'evento load o durante la gestione di eventi load

Le XMLHttpRequests sincrone prima dell'avvio di un evento load della pagina o durante la gestione dell'evento load non restituiscono alcun contenuto. Le XMLHttpRequests asincrone possono essere avviate, tuttavia non restituiranno contenuto fino al completamento dell'evento load . Dopo che l'evento load è stato gestito, le XMLHttpRequests sincrone si comportano normalmente.

Elementi di script creati dinamicamente

Gli elementi di script creati dinamicamente, ad esempio con innerHTML o con il metodo document.createElement , vengono ignorati.