Scripting tussen de inhoud van verschillende domeinen

Adobe AIR 1.0 of hoger

Bij de installatie van AIR-toepassingen worden hieraan speciale rechten toegewezen. Het is van groot belang dat deze rechten niet aan andere inhoud worden doorgegeven, zoals externe bestanden en lokale bestanden die geen deel uitmaken van de toepassing.

Informatie over de AIR-sandboxbridge

Inhoud van andere domeinen kan normaal gesproken geen scripts in andere domeinen oproepen. Om AIR-toepassingen te beschermen tegen onbedoelde lekkage van informatie of besturingselementen waarvoor speciale toegangsrechten gelden, gelden de volgende beperkingen voor de inhoud van de beveiligingssandbox application (inhoud die met de toepassing is geïnstalleerd):

  • Code in de toepassingsbeveiligingssandbox mag geen toegang bieden tot andere sandboxen door de methode Security.allowDomain() op te roepen. Het oproepen van deze methode vanuit de toepassingsbeveiligingssandbox veroorzaakt een fout.

  • Het importeren van niet-toepassingsinhoud in de toepassingssandbox door de eigenschap LoaderContext.securityDomain of LoaderContext.applicationDomain te activeren, wordt verhinderd.

Er zijn echter situaties waarin de AIR-hoofdtoepassing inhoud van een extern domein nodig heeft voor gecontroleerde toegang tot scripts in de AIR-hoofdtoepassing, of omgekeerd. Hiervoor biedt de runtime het mechanisme sandboxbridge , dat als gateway tussen beide sandboxen fungeert. Een sandboxbridge kan expliciete interactie tussen externe en toepassingsbeveiligingssandboxen bieden.

De sandboxbridge maakt twee objecten toegankelijk, waartoe zowel geladen als ladende scripts toegang hebben:

  • Het object parentSandboxBridge staat ladende inhoud toe om eigenschappen en functies toegankelijk te maken voor scripts in de geladen inhoud.

  • Het object childSandboxBridge staat geladen inhoud toe om eigenschappen en functies toegankelijk te maken voor scripts in de ladende inhoud.

Objecten die via de sandboxbridge toegankelijk worden gemaakt, worden doorgegeven op basis van waarde en niet op basis van referentie. Alle gegevens zijn geserialiseerd. Dit betekent dat de objecten die door de ene kant van de bridge toegankelijk zijn gemaakt, niet door de andere kant kunnen worden ingesteld, en dat alle toegankelijke objecten geen specifiek type hebben. Bovendien kunt u alleen eenvoudige objecten en functies toegankelijk maken, geen complexe objecten.

Als onderliggende inhoud een eigenschap van het object parentSandboxBridge probeert in te stellen, genereert de runtime een SecurityError-fout. Evenzo genereert de runtime een SecurityError-fout als bovenliggende inhoud een eigenschap van het object childSandboxBridge probeert in te stellen.

Voorbeeld van sandboxbridge (SWF)

Dit voorbeeld is gebaseerd op een AIR-toepassing voor een muziekwinkel. De toepassing wil externe SWF-bestanden toestaan om de prijs van albums toegankelijk te maken maar wil niet dat het externe SWF-bestand aangeeft of de prijs een opruimingsprijs is. Hiervoor biedt de klasse StoreAPI een methode die de prijs opvraagt maar de opruimingsprijs verbergt. Vervolgens wordt een instantie van deze StoreAPI-klasse toegewezen aan de eigenschap parentSandboxBridge van het LoaderInfo-object van het Loader-object dat het externe SWF-bestand laadt.

Dit is de code voor de AIR-muziekwinkel:

<?xml version="1.0" encoding="utf-8"?> 
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="Music Store" creationComplete="initApp()"> 
    <mx:Script> 
        import flash.display.Loader; 
        import flash.net.URLRequest; 
     
        private var child:Loader; 
        private var isSale:Boolean = false; 
         
        private function initApp():void { 
            var request:URLRequest =  
                    new URLRequest("http://[www.yourdomain.com]/PriceQuoter.swf") 
 
            child = new Loader(); 
            child.contentLoaderInfo.parentSandboxBridge = new StoreAPI(this); 
            child.load(request); 
            container.addChild(child); 
        } 
        public function getRegularAlbumPrice():String { 
            return "$11.99"; 
        } 
        public function getSaleAlbumPrice():String { 
            return "$9.99"; 
        } 
        public function getAlbumPrice():String { 
            if(isSale) { 
                return getSaleAlbumPrice(); 
            } 
            else { 
                return getRegularAlbumPrice();     
            } 
        } 
    </mx:Script> 
    <mx:UIComponent id="container" /> 
</mx:WindowedApplication> 

Het StoreAPI-object roept de hoofdtoepassing op om de normale albumprijs op te vragen maar geeft “Not available” (Niet beschikbaar) weer wanneer de methode getSaleAlbumPrice() wordt opgeroepen. De volgende code definieert de klasse StoreAPI:

public class StoreAPI 
{ 
    private static var musicStore:Object; 
     
    public function StoreAPI(musicStore:Object) 
    { 
        this.musicStore = musicStore; 
    } 
 
    public function getRegularAlbumPrice():String { 
        return musicStore.getRegularAlbumPrice(); 
    } 
     
    public function getSaleAlbumPrice():String { 
        return "Not available"; 
    } 
     
    public function getAlbumPrice():String { 
        return musicStore.getRegularAlbumPrice();     
    } 
}

De volgende code is een voorbeeld van het SWF-bestand PriceQuoter (Prijsofferte), dat de verkoopprijs van de winkel weergeeft maar de opruimingsprijs niet kan weergeven:

package 
{ 
    import flash.display.Sprite; 
    import flash.system.Security; 
    import flash.text.*; 
     
    public class PriceQuoter extends Sprite 
    { 
        private var storeRequester:Object; 
         
        public function PriceQuoter() { 
            trace("Initializing child SWF"); 
            trace("Child sandbox: " + Security.sandboxType); 
            storeRequester = loaderInfo.parentSandboxBridge; 
             
            var tf:TextField = new TextField(); 
            tf.autoSize = TextFieldAutoSize.LEFT; 
            addChild(tf); 
             
            tf.appendText("Store price of album is: " + storeRequester.getAlbumPrice()); 
            tf.appendText("\n"); 
            tf.appendText("Sale price of album is: " + storeRequester.getSaleAlbumPrice()); 
        } 
    } 
}

Voorbeeld van sandboxbridge (HTML)

Bij HTML-inhoud worden de eigenschappen parentSandboxBridge en childSandboxBridge toegevoegd aan het JavaScript window-object van een subdocument. Zie Sandboxbridge-interface instellen voor een voorbeeld van hoe u bridgefuncties definieert in HTML-inhoud.

API-toegankelijkheid beperken

Bij het toegankelijk maken van sandboxbridges is het belangrijk dat u API's toegankelijk maakt die van een hoog niveau zijn en de mate beperken waarin ze kunnen worden misbruikt. Vergeet niet dat de inhoud die uw bridge-implementatie oproept, door een kwaadwillige persoon kan zijn gewijzigd (bijvoorbeeld via een code-injectie). Dit betekent bijvoorbeeld dat een methode readFile(path:String) (die de inhoud van een willekeurig bestand leest) die via een bridge toegankelijk wordt gemaakt, kan worden misbruikt. Het is aan te raden een API readApplicationSetting() toegankelijk te maken die geen specifiek pad volgt en een specifiek bestand leest. De meer semantische methode beperkt de schade die een toepassing kan aanbrengen als een deel ervan door een kwaadwillige persoon is gewijzigd.