HTML-säkerhet i Adobe AIR

Adobe AIR 1.0 och senare

I det här avsnittet beskrivs AIR-arkitekturens HTML-säkerhet och hur du använder iframes, bildrutor och sandlådebryggan för att konfigurera HTML-baserade program och integrera HTML-innehåll i SWF-baserade program på ett säkert sätt.

Körtiden använder regler och innehåller mekanismer för att övervinna eventuella säkerhetssvagheter i HTML och JavaScript. Samma regler används oavsett om ditt program i huvudsak är skrivet i JavaScript eller om du läser in HTML- och JavaScript-innehållet till ett SWF-baserat program. Innehåll i programsandlådan och i icke-programsäkerhetssandlådan har olika rättigheter. När innehåll läses in till en bildruta eller iframe tillhandahåller körningsmiljön en säker funktion för sandlådebryggor , som tillåter innehåll i aktuell bildruta eller iframe att kommunicera säkert med innehåll i programsäkerhetssandlådan.

AIR SDK har tre klasser för återgivning av HTML-innehåll.

Klassen HTMLLoader ger en nära integrering mellan JavaScript-kod och API:erna i AIR.

Klassen StageWebView är en klass för HTML-återgivning och har mycket begränsad integrering med AIR-värdprogrammet. Innehåll som läses in av klassen StageWebView placeras aldrig i programmets säkerhetssandlåda och kan inte komma åt data eller anropa funktioner i AIR-värdprogrammet. På datorplattformar använder klassen StageWebView den inbyggda HTML-motorn i AIR, som bygger på Webkit, vilken också används av klassen HTMLLoader. På mobilplattformar använder klassen StageWebView operativsystemets HTML-kontroll. Därför har klassen StageWebView på mobilplattformar samma säkerhetsaspekter och -problem som systemets webbläsare.

Klassen TextField kan visa strängar med HTML-text. Ingen JavaScript-kod kan köras, men texten kan innehålla länkar och externa bilder.

Mer information finns under Undvika säkerhetsrelaterade JavaScript-fel .

Översikt över att konfigurera ditt HTML-baserade program

Frames och iframes är ett bekvämt sätt att strukturera och organisera HTML-innehåll i AIR. Frames är ett sätt att både behålla databeständighet och att arbeta säkert med fjärrinnehåll.

Eftersom HTML i AIR bevarar sin normala sidbaserade organisering, kommer HTML-miljön att uppdateras fullständigt om HTML-innehållets huvud-frame öppnar en annan sida. Du kan använda frames och iframes för att behålla databeständighet i AIR, på samma sätt som du skulle göra för ett webbprogram som körs i en webbläsare. Om du definierar dina huvudsakliga programobjekt i programmets huvud-frame, kommer de att finnas kvar så länge du inte låter programmets huvud-frame gå till en ny sida. Använd underordnade frames eller iframes för att läsa in och visa programmets tillfälliga delar. (Det finns ett flertal sätt att behålla databeständighet som kan användas tillsammans med eller istället för frames. De är bland annat cookies, lokala delade objekt, lokal fillagring, den krypterade fillagringsplatsen och lokal databaslagring.)

Eftersom gränsen mellan körbar kod och data i HTML är suddig även i AIR, placeras innehåll i den översta bildrutan i HTML-miljön i programsandlådan. Efter load -händelsen för sidan begränsar AIR alla åtgärder, t.ex. eval() , som kan konvertera en sträng med text till ett körbart objekt. Den här begränsningen används till och med när ett program inte läser in fjärrinnehåll. Om du vill tillåta att HTML-innehåll kör dessa begränsade åtgärder måste du använda frames eller iframes för att placera innehållet i en icke-programsandlåda. (Du kan behöva köra innehåll i en underordnad bildruta som placerats i en sandlåda när du använder vissa JavaScript-programramverk som använder funktionen eval() .) En fullständig lista över begränsningar för JavaScript i programsandlådan finns under Kodrestriktioner för innehåll i olika sandlådor .

Eftersom HTML i AIR behåller sin förmåga att läsa in potentiellt osäkert fjärrinnehåll, använder AIR en samma-ursprung-policy som förhindrar att innehåll i en domän interagerar med innehåll i en annan. För att tillåta interaktion mellan programinnehåll och innehåll i en annan domän, kan du konfigurera en brygga som fungerar som gränssnittet mellan en huvud-frame och en underordnad frame.

Konfigurera en överordnad-underordnad sandlåderelation

AIR lägger till attributen sandboxRoot och documentRoot till frame- och iframe-elementen för HTML. Med dessa attribut kan du behandla programinnehåll som om det kom från en annan domän:

Attribut

Beskrivning

sandboxRoot

Den URL som används för att avgöra viken sandlåda och vilken domän som frame-innehåll ska placeras i. URL-schemat file: , http: eller https: måste användas.

documentRoot

Den URL från vilken frame-innehåll ska läsas in. URL-schemat file: , app: eller app-storage: måste användas.

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

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

Konfigurera en brygga mellan huvud-frames och underordnade frames i olika sandlådor eller domäner

AIR lägger till egenskaperna childSandboxBridge och parentSandboxBridge till objektet window i alla underordnade frames. Med dessa egenskaper kan du definiera bryggor som fungerar som ett gränssnitt mellan en överordnad och en underordnad frame. Varje brygga går i en riktning:

childSandboxBridge - Egenskapen childSandboxBridge gör att en underordnad frame kan visa ett gränssnitt till innehåll i sin överordnade frame. Visa ett gränssnitt genom att ange egenskapen childSandbox till en funktion eller ett objekt i en underordnad frame. Sedan kan du komma åt objektet eller funktionen från innehåll i dess överordnade frame. Följande exempel visar hur ett skript som körs i en underordnad frame kan visa ett objekt som innehåller en funktion och en egenskap för dess överordnade frame.

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

Om detta underordnade innehåll finns i en iframe som är tilldelad ett id "child" , kan du komma åt gränssnittet från överordnat innehåll genom att läsa frame-egenskapen childSandboxBridge .

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

parentSandboxBridge - Egenskapen parentSandboxBridge gör att en överordnad frame kan visa ett gränssnitt till innehåll i sin underordnade frame. Visa ett gränssnitt genom att ange egenskapen parentSandbox i en underordnad frame till en funktion eller ett objekt i dess överordnade frame. Sedan kan du komma åt objektet eller funktionen från innehåll i dess underordnade frame. Följande exempel visar hur ett skript som körs i en överordnad frame kan visa ett objekt som innehåller en spara-funktion för sin underordnade frame:

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

Med detta gränssnitt kan innehåll i den underordnade framen spara text till en fil som heter save.txt. Den skulle dock inte ha någon annan tillgång till filsystemet. I allmänhet bör programinnehåll visa ett så litet gränssnitt som möjligt för andra sandlådor. Det underordnade innehållet kan anropa save-funktionen på följande sätt:

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

Om underordnat innehåll försöker ange en egenskap för objektet parentSandboxBridge , utlöser körtiden ett SecurityError-undantag. Om överordnat innehåll försöker ange en egenskap för objektet childSandboxBridge , utlöser körtiden ett SecurityError-undantag.

Kodrestriktioner för innehåll i olika sandlådor

Som tidigare nämnts i inledningen till det här avsnittet, HTML-säkerhet i Adobe AIR , innehåller körningsmiljön regler och mekanismer för att hantera eventuella säkerhetsbrister i HTML och JavaScript. Detta avsnitt listar dessa begränsningar. Om kod försöker anropa dessa begränsade API:er utlöser körtiden ett fel med meddelandet ”Säkerhetsöverträdelse i Adobe AIR-körtiden för JavaScript-kod i programsäkerhetssandlådan”.

Mer information finns under Undvika säkerhetsrelaterade JavaScript-fel .

Begränsningar för användning av JavaScript-funktionen eval() och liknande tekniker

Det finns begränsningar för HTML-innehåll i programsäkerhetssandlådan för att använda API:er som kan omvandla strängar dynamiskt till körbar kod efter att koden har lästs in (efter att händelsen onload i body -elementet har skickats och körningen av onload -hanterarfunktionen är slutförd). Detta är till för att förhindra programmet från att av misstag föra in (och köra) kod från källor som inte tillhör programmet (som till exempel potentiellt osäkra nätverksdomäner).

Om ditt program till exempel använder strängdata från en fjärrkälla för att skriva till egenskapen innerHTML i ett DOM-element, skulle strängen kunna innehålla körbar (JavaScript) kod som skulle kunna utföra osäkra operationer. Det är dock ingen risk att fjärrsträngar förs in i DOM medan innehållet laddas.

En begränsning är användandet av JavaScript-funktionen eval() . När kod i programsandlådan väl är inläst och efter bearbetning av onload-händelsehanteraren, kan du endast använda funktionen eval() på begränsade sätt. Följande regler gäller för användande av funktionen eval() efter att kod är inläst från programsäkerhetssandlådan:

  • Uttryck som innefattar litteraler är tillåtna. Till exempel:

    eval("null"); 
    eval("3 + .14"); 
    eval("'foo'");
  • Objektlitteraler är tillåtna, som i följande:

    { prop1: val1, prop2: val2 }
  • Set-/get-metoder för objektlitteraler är ej tillåtna , som i följande:

    { get prop1() { ... }, set prop1(v) { ... } }
  • Arraylitteraler är tillåtna, som i följande:

    [ val1, val2, val3 ]
  • Uttryck som innefattar egenskapsläsningar är ej tillåtna , som i följande:

    a.b.c
  • Funktionsanrop är ej tillåtna.

  • Funktionsdefinitioner är ej tillåtna.

  • Inställning av egenskaper är ej tillåten.

  • Funktionslitteraler är ej tillåtna.

Medan koden läses in, innan onload -händelsen och under körningen av onload -händelsehanterarfunktionen, gäller dock dessa begränsningar inte för innehåll i programsäkerhetssandlådan.

Efter att exempelvis kod har lästs in, resulterar följande kod i att körtiden utlöser ett undantag:

eval("alert(44)"); 
eval("myFunction(44)"); 
eval("NativeApplication.applicationID");

Dynamiskt genererad kod som till exempel den som tillverkas när funktionen eval() anropas skulle utgöra en säkerhetsrisk om den var tillåten inuti programsandlådan. Ett program kan till exempel av misstag köra en sträng som är inläst från en nätverksdomän, och den strängen kan innehålla uppsåtlig kod. Detta skulle till exempel kunna vara kod för att ta bort eller ändra filer på användarens dator. Det skulle också kunna vara kod som rapporterar innehållet i en lokal fil till en icke tillförlitlig nätverksdomän.

Följande sätt att generera dynamisk kod finns:

  • Anropa funktionen eval() .

  • Använda innerHTML -egenskaper eller DOM-funktioner för att infoga script-taggar som läser in ett skript utanför programkatalogen.

  • Använda innerHTML -egenskaper eller DOM-funktioner för att infoga script-taggar som har intern kod (istället för att läsa in ett skript via attributet src ).

  • Ställa in attributet src för en script -tagg till att läsa in en JavaScript-fil som ligger utanför programkatalogen.

  • Använda URL-schemat javascript (som i href="javascript:alert('Test')" ).

  • Använda funktionen setInterval() eller setTimout() där den första parametern (som definierar att funktionen ska köras asynkront) är en sträng (som ska utvärderas) istället för ett funktionsnamn (som i setTimeout('x = 4', 1000) ).

  • Anropa document.write() eller document.writeln() .

Kod som finns i programsäkerhetssandlådan kan bara använda dessa metoder medan innehåll läses in.

Dessa begränsningar förhindrar inte användandet av eval() med JSON-objektlitteraler. Detta gör att ditt programinnehåll kan arbeta med JavaScript-biblioteket JSON. Du hindras dock från att använda överlagrad JSON-kod (med händelsehanterare).

Om du vill använda andra Ajax-ramverk och JavaScript-kodbibliotek, bör du kontrollera om kod i ramverket eller biblioteket fungerar inom dessa restriktioner för dynamiskt genererad kod. Om de inte fungerar, ska du inkludera allt innehåll som använder ramverket eller biblioteket i en icke-programsäkerhetssandlåda. Mer information finns i Begränsningar för JavaScript inne i AIR och Skriptning mellan program- och icke-programinnehåll . Adobe har en lista över Ajax-ramverk som stöder programsäkerhetssandlådan på http://www.adobe.com/products/air/develop/ajax/features/ .

Till skillnad från innehåll i programsäkerhetssandlådan, kan JavaScript-innehåll i en icke-programsäkerhetssandlåda anropa funktionen eval() för att när som helst köra dynamiskt genererad kod.

Begränsningar i tillgång till AIR-API:er (för icke-programsandlådor)

JavaScript-kod i en icke-programsandlåda har inte tillgång till objektet window.runtime , och kan därför inte köra AIR-API:er. Om innehåll i en icke-programsäkerhetssandlåda anropar följande kod, utlöser programmet ett TypeError-undantag:

try { 
    window.runtime.flash.system.NativeApplication.nativeApplication.exit(); 
}  
catch (e)  
{ 
    alert(e); 
}

Undantagstypen är TypeError (odefinierat värde) eftersom innehållet i icke-programsandlådan inte känner igen objektet window.runtime , vilket gör att det ses som ett odefinierat värde.

Du kan visa körtidsfunktioner för innehåll i en icke-programsandlåda genom att använda en skriptbrygga. Fler detaljer finns under Skriptning mellan program- och icke-programinnehåll .

Begränsningar i att använda XMLHttpRequest-anrop

HTML-innehåll i programsäkerhetssandlådan kan inte använda synkrona XMLHttpRequest-metoder för att läsa in data som ligger utanför programsandlådan medan HTML-innehållet läses in och under onLoad -händelsen.

Som standard tillåts inte HTML-innehåll i icke-programsäkerhetssandlådor att använda JavaScript-objektet XMLHttpRequest för att läsa in data från andra domäner än den domän som anropar begäran. En frame - eller iframe -tagg kan innehålla ett allowcrosscomainxhr -attribut. Om det här attributet ställs in på ett värde som inte är null kan innehållet i bildrutan eller iframe använda JavaScript-objektet XMLHttpRequest för att läsa in data från andra domäner än den anropande kodens domän:

<iframe id="UI" 
    src="http://example.com/ui.html" 
    sandboxRoot="http://example.com/" 
    allowcrossDomainxhr="true" 
    documentRoot="app:/"> 
</iframe>

Mer information finns under Skriptning mellan innehåll i olika domäner .

Begränsningar för att läsa in CSS-, frame-, iframe- och img-element (för innehåll i icke-programsandlådor)

HTML-innehåll i fjärrsäkerhetssandlådor (nätverk) kan bara läsa in CSS-, frame -, iframe - och img -innehåll från fjärrsandlådor (från nätverks-URL:er).

HTML-innehåll i sandlådor av typerna lokal-med-filsystem, lokal-med-nätverk eller lokal-tillförlitlig, kan endast läsa in CSS-, frame-, iframe- och img -innehåll från lokala sandlådor (inte från program- eller fjärrsandlådor).

Begränsningar för anrop till JavaScript-metoden window.open()

Om ett fönster som skapas via ett anrop till JavaScript-metoden window.open() visar innehåll från en icke-programsäkerhetssandlåda, börjar fönstrets titel med huvudfönstrets (det skapande fönstret) titel, följt av tecknet kolon. Du kan inte använda kod för att flytta den delen av fönstertiteln utanför skärmen.

Innehåll i en icke-programsäkerhetssandlåda kan endast anropa JavaScript-metoden window.open() som svar på en händelse som triggas av en användarinteraktion med musen eller tangentbordet. Detta förhindrar att icke-programinnehåll skapar fönster som kan användas bedrägligt (till exempel för nätfiskeattacker). Händelsehanteraren för en mus- eller tangentbordshändelse kan inte heller ställa in metoden window.open() till att köras efter en fördröjning (genom att till exempel anropa funktionen setTimeout() ).

Innehåll i fjärrsandlådor (nätverk) kan bara använda metoden window.open() för att öppna innehåll i fjärrnätverkssandlådor. Det kan inte använda metoden window.open() för att öppna innehåll från programsandlådan eller lokala sandlådor.

Innehåll i sandlådorna lokal-med-filsystem, lokal-med-nätverk eller lokal-tillförlitlig (se Säkerhetssandlådor ) kan bara använda metoden window.open() för att öppna innehåll i lokala sandlådor. Det kan inte använda metoden window.open() för att öppna innehåll från programsandlådan eller fjärrsandlådor.

Fel vid anrop till begränsad kod

Om du anropar kod som är begränsad för användning i en sandlåda på grund av dessa säkerhetsbegränsningar, genererar körtiden ett JavaScript-fel: ”Säkerhetsöverträdelse i Adobe AIR-körtiden för JavaScript-kod i programsäkerhetssandlådan.”

Mer information finns under Undvika säkerhetsrelaterade JavaScript-fel .

Sandlådeskydd vid inläsning av HTML-innehåll från en sträng

Med HTMLLoader-klassens loadString() -metod kan du skapa HTML-innehåll vid körning. Informationen som du använder som HTML-innehåll kan emellertid vara skadlig om den kommer från en osäker Internetkälla. Av den anledningen placeras inte HTML-innehåll som skapats med loadString() -metoden i programsandlådan som standard, och innehållet har inte åtkomst till AIR-API:erna. Du kan emellertid ändra värdet för placeLoadStringContentInApplicationSandbox -egenskapen för ett HTMLLoader-objekt till true om du vill att HTML-innehåll som skapats med loadString() -metoden ska placeras i programsandlådan. Mer information finns i avsnittet Läsa in HTML-innehåll från en sträng .