Creazione di script tra contenuti in diversi domini

Adobe AIR 1.0 e versioni successive

Alle applicazioni AIR vengono concessi privilegi speciali al momento dell'installazione. È fondamentale che gli stessi privilegi non vengano diffusi ad altro contenuto, ad esempio file remoti e file locali che non fanno parte dell'applicazione.

Informazioni sul bridge sandbox AIR

In genere, il contenuto da altri domini non può chiamare script in altri domini. Per proteggere le applicazioni AIR dalla diffusione accidentale del controllo o di informazioni con privilegi, vengono applicate le seguenti restrizioni al contenuto presente nella sandbox di sicurezza application (il contenuto installato con l'applicazione):

  • Il codice nella sandbox di sicurezza dell'applicazione non può consentire l'accesso ad altre sandbox mediante una chiamata al metodo Security.allowDomain() . Se chiamate questo metodo dalla sandbox di sicurezza dell'applicazione, viene generato un errore.

  • L'importazione di contenuto non dell'applicazione nella sandbox dell'applicazione mediante l'impostazione della proprietà LoaderContext.securityDomain o LoaderContext.applicationDomain non è consentita.

Vi sono tuttavia alcuni casi in cui l'applicazione AIR principale richiede che il contenuto da un dominio remoto disponga dell'accesso controllato agli script nell'applicazione AIR principale o viceversa. A questo scopo, il runtime fornisce un meccanismo bridge sandbox che funge da gateway tra le due sandbox. Un bridge sandbox può fornire l'interazione esplicita tra le sandbox di sicurezza remota e dell'applicazione.

Il bridge sandbox espone due oggetti a cui possono accedere gli script caricati e in fase di caricamento:

  • L'oggetto parentSandboxBridge consente al contenuto in fase di caricamento di esporre proprietà e funzioni agli script nel contenuto caricato.

  • L'oggetto childSandboxBridge consente al contenuto caricato di esporre proprietà e funzioni agli script nel contenuto in fase di caricamento.

Gli oggetti esposti tramite il bridge sandbox vengono passati in base al valore, non al riferimento. Tutti i dati sono serializzati. Ciò significa che gli oggetti esposti da un lato del bridge non possono essere impostati dall'altro lato, e che gli oggetti esposti sono tutti senza tipo. Inoltre, potete esporre solo semplici oggetti e funzioni; non potete esporre oggetti complessi.

Se il contenuto secondario tenta di impostare una proprietà dell'oggetto parentSandboxBridge, il runtime genera un'eccezione SecurityError. In modo analogo, se il contenuto principale tenta di impostare una proprietà dell'oggetto childSandboxBridge, il runtime genera un'eccezione SecurityError.

Esempio di bridge sandbox (SWF)

Supponete di voler fare in modo che un'applicazione AIR per un negozio di musica consenta ai file SWF remoti di diffondere il prezzo degli album, impedendo tuttavia che il file SWF remoto riveli se si tratta del prezzo di vendita. A questo scopo, la classe StoreAPI fornisce un metodo per acquisire il prezzo, nascondendo però il prezzo di vendita. Un'istanza di questa classe StoreAPI viene quindi assegnata alla proprietà parentSandboxBridge dell'oggetto LoaderInfo dell'oggetto Loader che carica il file SWF remoto.

Di seguito è riportato il codice dell'applicazione AIR per il negozio di musica:

<?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> 

L'oggetto StoreAPI chiama l'applicazione principale per recuperare il normale prezzo dell'album, ma restituisce "Non disponibile" quando viene chiamato il metodo getSaleAlbumPrice() . Il seguente codice definisce la classe 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();     
    } 
}

Il seguente codice rappresenta un esempio di file SWF denominato PriceQuoter SWF che indica il prezzo del negozio, ma non può indicare il prezzo di vendita:

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

Esempio di bridge sandbox (HTML)

Nel contenuto HTML, le proprietà parentSandboxBridge e childSandboxBridge vengono aggiunte all'oggetto JavaScript window di un documento secondario. Per un esempio di impostazione delle funzioni del bridge nel contenuto HTML, consultate Impostazione dell'interfaccia per un bridge sandbox .

Limitazione dell'esposizione delle API

Quando esponete i bridge sandbox, è importante esporre le API di alto livello che limitano il grado a cui potrebbero essere usate in modo improprio. Tenete presente che il contenuto che chiama la vostra implementazione del bridge potrebbe risultare compromesso (ad esempio, mediante introduzione, ovvero injection, di codice). Pertanto, l'esposizione, ad esempio, di un metodo readFile(path:String) (che legge il contenuto di un file arbitrario) tramite un bridge è soggetto a un uso abusivo. Sarebbe preferibile esporre un'API readApplicationSetting() che non segue un percorso e legge un file specifico. Un approccio più semantico limita il danno che potrebbe provocare un'applicazione qualora una parte di essa venisse compromessa.