JavaScript-beveiligingsfouten voorkomen

Adobe AIR 1.0 of hoger

Als u code oproept die niet in een sandbox kan worden gebruikt vanwege deze beveiligingsbeperkingen, geeft de runtime de foutmelding weer dat er in de runtime van Adobe AIR een beveiligingsfout betreffende JavaScript-code in de toepassingsbeveiligingssandbox is opgetreden. Ga als volgt te werk om deze fout te voorkomen.

Oorzaken van JavaScript-beveiligingsfouten

Code die wordt uitgevoerd in de toepassingssandbox, is uitgesloten van de meeste bewerkingen waarbij tekenreeksen worden geëvalueerd en uitgevoerd nadat de documentgebeurtenis load is geactiveerd en eventuele handlers voor de gebeurtenis load zijn afgesloten. Als u de volgende typen JavaScript-instructies gebruikt die potentieel onveilige tekenreeksen evalueren en uitvoeren, worden JavaScript-fouten gegenereerd:

Toepassingsinhoud toewijzen aan een andere sandbox

In de meeste gevallen kunt u een toepassing aanpassen of opnieuw structureren, zodat JavaScript-beveiligingsfouten worden voorkomen. Als aanpassen of opnieuw structureren echter niet mogelijk is, kunt u de inhoud van de toepassing in een andere sandbox laden met de techniek die is beschreven in Toepassingsinhoud laden in een niet-toepassingssandbox . Als deze inhoud ook toegang moet hebben tot de API's van AIR, kunt u een sandboxbridge maken, zoals beschreven in Sandboxbridge-interface instellen .

eval(), functie

In de toepassingssandbox kunt u de functie eval() alleen gebruiken vóór de gebeurtenis load van de pagina of tijdens de gebeurtenishandler load . Nadat de pagina is geladen, wordt geen code uitgevoerd als eval() wordt opgeroepen. In de volgende gevallen kunt u uw code echter aanpassen om het gebruik van eval() te voorkomen.

Eigenschappen toewijzen aan een object

In plaats van een tekenreeks te parseren om de eigenschapsaccessor te bouwen:

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

roep eigenschappen op met haakjesnotering:

obj[propName] = val;

Functies maken met variabelen die beschikbaar zijn in de context

Vervang instructies zoals deze:

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

door:

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

Objecten maken met de naam van de klasse als tekenreeksparameter

Bekijken we een hypothetische JavaScript-klasse die met de volgende code is gedefinieerd:

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

De eenvoudigste manier om een instantie te maken, is met behulp van eval() :

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

U kunt het oproepen van eval() echter voorkomen door elke component van de klassennaam te parseren en het nieuwe object op te bouwen met behulp van de haakjesnotering:

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

Om de instantie te maken, gebruikt u:

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

setTimeout() en setInterval()

Vervang de tekenreeks die als handlerfunctie is opgegeven, door een functieverwijzing of een object. Voorbeeld: vervang een instructie zoals:

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

door:

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

Of, als de functie vereist dat het object this wordt ingesteld door de oproeper, vervangt u een instructie zoals:

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

door het volgende:

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

Functieconstructor

Oproepen van new Function(param, body) kunnen worden vervangen door een inline functiedeclaratie of alleen worden gebruikt voordat de gebeurtenis load van de pagina is afgehandeld.

javascript: URL's

De code die in een koppeling met behulp van het URL-schema javascript: is gedefinieerd, wordt in de toepassingssandbox genegeerd. Er wordt geen JavaScript-fout voor onveilige inhoud gegenereerd. U kunt koppelingen vervangen die gebruikmaken van URL's van het type javascript:, zoals:

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

door:

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

Gebeurteniscallbacks die via onevent-kenmerken in innerHTML- en outerHTML-instructies zijn toegewezen

Als u innerHTML of outerHTML gebruikt om elementen toe te voegen aan de DOM van een document, worden gebeurteniscallbacks die in de instructie zijn toegewezen, zoals onclick of onmouseover , genegeerd. Er wordt geen beveiligingsfout gegenereerd. In plaats daarvan kunt u het kenmerk id aan de nieuwe elementen toewijzen en de callbackfuncties van de gebeurtenishandler instellen met de methode addEventListener() .

U hebt bijvoorbeeld een doelelement in een document, zoals:

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

Vervang instructies zoals:

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

door:

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

JavaScript-bestanden laden van buiten de installatiemap van de toepassing

Scriptbestanden kunnen niet van buiten de toepassingssandbox worden geladen. Er wordt geen beveiligingsfout gegenereerd. Alle scriptbestanden die in de toepassingssandbox worden uitgevoerd, moeten in de toepassingsmap zijn geïnstalleerd. Als u externe scripts in een pagina wenst te gebruiken, moet u de pagina toewijzen aan een andere sandbox. Zie Toepassingsinhoud laden in een niet-toepassingssandbox .

document.write() en document.writeln()

Oproepen van document.write() of document.writeln() worden genegeerd nadat de gebeurtenis load van de pagina is afgehandeld. Er wordt geen beveiligingsfout gegenereerd. Als alternatief kunt u een nieuw bestand laden of de hoofdtekst van het document vervangen met behulp van DOM-manipulatietechnieken.

Synchrone XMLHttpRequests vóór de gebeurtenis load of tijdens de gebeurtenishandler load

Synchrone XMLHttpRequests die worden gestart vóór de gebeurtenis load van de pagina of tijdens de handler voor de gebeurtenis load , retourneren geen inhoud. Asynchrone XMLHttpRequests kunnen worden gestart maar retourneren pas na de gebeurtenis load . Nadat de gebeurtenis load is afgehandeld, gedragen synchrone XMLHttpRequests zich op de normale manier.

Dynamisch gecreëerde scriptelementen

Scriptelementen die dynamisch zijn gecreëerd, bijvoorbeeld met innerHTML of de methode document.createElement() , worden genegeerd.