Korsskriptning av innehåll i olika säkerhetssandlådor

Adobe AIR 1.0 och senare

Runtime-modulens säkerhetsmodell isolerar kod av olika ursprung. Genom att använda korsskriptning av innehåll i olika säkerhetssandlådor kan du tillåta att innehåll i en säkerhetssandlåda får tillgång till valda egenskaper och metoder i en annan sandlåda.

AIR-säkerhetssandlådor och JavaScript-kod

AIR använder en policy för samma ursprung som förhindrar att kod från en domän interagerar med innehåll i en annan. Alla filer placeras i en sandlåda utifrån sitt ursprung. I vanliga fall kan inte innehåll i programsandlådan bryta mot principen om samma ursprung och göra korsskriptning av innehåll som läses in från en annan plats utanför programinstallationskatalogen. I AIR finns dock ett par tekniker som gör att du kan utföra korsskriptning på icke-programinnehåll.

I en teknik används frames eller iframes för att mappa programinnehåll till en annan säkerhetssandlåda. Sidor som blir inlästa från programmets sandlådeområde fungerar på samma sätt som om de vore inlästa från en fjärrdomän. Om programinnehåll till exempel mappas till domänen example.com kan innehållet utföra korsskriptning på sidor som lästs in från example.com.

Eftersom den här tekniken placerar programinnehållet i en annan sandlåda, omfattas inte längre koden i innehållet av begränsningarna för körning av kod i utvärderade strängar. Du kan använda den här tekniken för sandlådemappning för att förenkla dessa begränsningar även om du inte behöver utföra korsskriptning på fjärrinnehåll. Att mappa innehåll på det här sättet kan vara användbart om du arbetar med ett av många JavaScript-ramverk eller med befintliga koder som är beroende av utvärderande strängar. Du bör dock överväga de risker det innebär om otillförlitligt innehåll infogas och utförs när innehåll körs utanför programsandlådan.

Programinnehåll som mappas till en annan sandlåda förlorar också åtkomsten till programgränssnitten i AIR, så tekniken för sandlådemappning kan inte användas för att göra AIR-funktioner tillgängliga för kod som körs utanför programsandlådan.

Med en annan teknik för korsskriptning kan du skapa ett gränssnitt, som kallas sandlådebrygga , mellan innehållet i en icke-programsandlåda och dess överordnade dokument i programsandlådan. Bryggan gör att det underordnade innehållet får åtkomst till egenskaper och metoder som har definierats av det överordnade innehållet, det överordnade innehållet får åtkomst till de egenskaper och metoder som definierats av det underordnade innehållet eller både och.

Du kan också utföra XMLHttpRequests mellan olika domäner från programsandlådan och från andra sandlådor.

Mer information finns i Bildrute- och iframe-element i HTML , HTML-säkerhet i Adobe AIR och Objektet XMLHttpRequest .

Läsa in programinnehåll i en icke-programsandlåda

Om du vill tillåta att programinnehåll ska kunna utföra säker korsskriptning på innehåll som lästs in från en annan plats än programinstallationskatalogen, kan du använda elementen frame eller iframe för att läsa in programinnehåll i samma säkerhetssandlåda som det externa innehållet. Om du inte behöver utföra korsskriptning på fjärrinnehåll men ändå vill läsa in en sida av programmet som är utanför programsandlådan, kan du använda samma teknik och ange http://localhost/ eller något annat neutralt värde som ursprungsdomän.

AIR lägger till nya attribut, sandboxRoot och documentRoot , till det frame-element som gör att du kan ange om en programfil som är inläst i ramen ska mappas till en icke-programsandlåda. Filer som relaterar till en sökväg under sandboxRoot -URL:en blir i stället inlästa från documentRoot -katalogen. Av säkerhetsskäl behandlas programinnehåll som lästs in på det här sättet som om det var inläst från sandboxRoot -URL:en.

Egenskapen sandboxRoot anger den URL som ska användas för att bestämma i vilken sandlåda och domän som raminnehållet ska placeras. URL-schemat file: , http: eller https: måste användas. Om du anger en relativ URL ligger innehållet kvar i programsandlådan.

Egenskapen documentRoot anger den katalog som raminnehållet ska läsas in från. URL-schemat file: , app: eller app-storage: måste användas.

I följande exempel mappas innehåll som är installerat i sandbox -underkatalogen i programmet så att det körs i fjärrsandlådan och domänen www.example.com :

<iframe 
    src="http://www.example.com/local/ui.html"  
    sandboxRoot="http://www.example.com/local/"  
    documentRoot="app:/sandbox/"> 
</iframe>

Sidan ui.html kunde läsa in en javascript-fil från den lokala sandbox -mappen med hjälp av följande skripttagg:

<script src="http://www.example.com/local/ui.js"></script>

Den kunde också läsa in innehåll från en katalog på fjärrservern med hjälp av en script-tagg som den nedan:

<script src="http://www.example.com/remote/remote.js"></script>

sandboxRoot -URL:en maskerar innehåll som finns på samma URL på fjärrservern. I exemplet ovan skulle du inte kunna få åtkomst till fjärrinnehåll på www.example.com/local/ (eller någon av dess underkataloger), eftersom AIR mappar om begäran till den lokala programkatalogen. Begäran mappas om oavsett om den härleds från sidnavigering, från en XMLHttpRequest eller från något annat sätt att läsa in innehåll.

Konfigurera ett gränssnitt för en sandlådebrygga

Du kan använda en sandlådebrygga om innehåll i programsandlådan måste ha tillgång till egenskaper och metoder som definierats av innehåll i en icke-programsandlåda eller om icke-programinnehåll måste ha tillgång till egenskaper och metoder som definierats av innehåll i programsandlådan. Skapa en brygga med hjälp av egenskaperna childSandboxBridge och parentSandboxBridge i window -objektet för ett underordnat dokument.

Skapa en underordnad sandlådebrygga

Egenskapen childSandboxBridge gör att det underordnade dokumentet kan visa ett gränssnitt för innehåll i det överordnade dokumentet. Om du vill visa ett gränssnitt anger du egenskapen childSandbox som en funktion eller ett objekt i det underordnade dokumentet. Du kan sedan få åtkomst till objektet eller funktionen via innehåll i det överordnade dokumentet. Följande exempel visar hur ett skript som körs i ett underordnat dokument kan visa ett objekt som innehåller en funktion och en egenskap för dess överordnade dokument:

var interface = {}; 
interface.calculatePrice = function(){ 
    return ".45 cents"; 
} 
interface.storeID = "abc" 
window.childSandboxBridge = interface;

Om det här underordnade innehållet lästes in i ett iframe-element som tilldelats ID ”child”, kan du få åtkomst till gränssnittet via det överordnade innehållet genom att läsa egenskapen childSandboxBridge i frame-elementet:

var childInterface = document.getElementById("child").contentWindow.childSandboxBridge; 
air.trace(childInterface.calculatePrice()); //traces ".45 cents" 
air.trace(childInterface.storeID)); //traces "abc"

Skapa en överordnad sandlådebrygga

Egenskapen parentSandboxBridge gör att det överordnade dokumentet kan visa ett gränssnitt för innehåll i det underordnade dokumentet. Om du vill visa ett gränssnitt anger det överordnade dokumentet egenskapen parentSandbox i det underordnade dokumentet som en funktion eller ett objekt som definieras i det överordnade dokumentet. Du kan sedan få åtkomst till objektet eller funktionen via innehåll i det underordnade dokumentet. Följande exempel visar hur ett skript som körs i ett överordnat frame-element kan visa ett objekt som innehåller en funktion för ett underordnat dokument:

var interface = {}; 
interface.save = function(text){ 
    var saveFile = air.File("app-storage:/save.txt"); 
    //write text to file 
} 
document.getElementById("child").contentWindow.parentSandboxBridge = interface;

Om du använder det här gränssnittet kan innehåll i det underordnade frame-elementet spara text till en fil med namnet save.txt , men det har ingen åtkomst till filsystemet. Det underordnade innehållet kan anropa save-funktionen på följande sätt:

var textToSave = "A string."; 
window.parentSandboxBridge.save(textToSave);

Programinnehåll ska visa ett så begränsat gränssnitt som möjligt för andra sandlådor. Icke-programinnehåll ska hanteras som otillförlitligt eftersom det kan vara utsatt för skadlig kod eller kod som angetts av misstag. Du måste vidta säkerhetsåtgärder för att förhindra obehörig användning av gränssnittet som du visar via den överordnade sandlådebryggan.

Åtkomst till överordnad sandlådebrygga under inläsning av sida

För att ett skript i ett underordnat dokument ska kunna få åtkomst till en överordnad sandlådebrygga måste bryggan vara inställd innan skriptet körs. Window-, frame- och iframe-objekten skickar en dominitialize -händelse när DOM för en ny sida har skapats, innan några skript har tolkats eller några DOM-element har lagts till. Du kan använda dominitialize -händelsen för att skapa bryggan tidigt i sidkonstruktionsprocessen så att alla skript i det underordnade dokumentet får åtkomst till den.

Följande exempel visa hur du skapar en överordnad sandlådebrygga som svar på den dominitialize -händelse som skickas från det underordnade frame-objektet:

<html> 
<head> 
<script> 
var bridgeInterface = {}; 
bridgeInterface.testProperty = "Bridge engaged"; 
function engageBridge(){ 
    document.getElementById("sandbox").contentWindow.parentSandboxBridge = bridgeInterface; 
} 
</script> 
</head> 
<body> 
<iframe id="sandbox" 
            src="http://www.example.com/air/child.html"  
            documentRoot="app:/" 
            sandboxRoot="http://www.example.com/air/" 
            ondominitialize="engageBridge()"/> 
</body> 
</html>

Följande child.html -dokument visar hur underordnat innehåll får åtkomst till den överordnade sandlådebryggan:

<html> 
    <head> 
        <script> 
            document.write(window.parentSandboxBridge.testProperty); 
        </script>   
    </head>   
    <body></body> 
</html>

Om du vill avlyssna dominitialize -händelsen i ett underordnat window-objekt, i stället för ett frame-objekt, måste du lägga till avlyssnaren i det nya underordnade window-objektet som skapas av window.open() -funktionen:

var childWindow = window.open(); 
childWindow.addEventListener("dominitialize", engageBridge()); 
childWindow.document.location = "http://www.example.com/air/child.html";

I så fall går det inte att mappa programinnehåll till en icke-programsandlåda. Den här tekniken är bara användbar när child.html har lästs in från en plats utanför programkatalogen. Du kan fortfarande mappa programinnehåll i window-objektet till en icke-programsandlåda, men du måste först läsa in en mellanliggande sida som själv använder ramar för att läsa in det underordnade dokumentet och mappa det till önskad sandlåda.

Om du använder funktionen createRootWindow() i klassen HTMLLoader för att skapa ett fönster är det nya fönstret inte underordnat det dokument som createRootWindow() anropas från. Du kan därför inte skapa en sandlådebrygga från det anropande fönstret till icke-programinnehåll som blir inläst i det nya fönstret. Du måste i stället läsa in en mellanliggande sida i det nya fönstret som själv använder ramar för att kunna läsa in det underordnade dokumentet. Du kan sedan skapa bryggan från det överordnade dokumentet i det nya fönstret till det underordnade dokumentet som blir inläst i ramen.