In dit onderwerp wordt de AIR HTML-beveiligingsarchitectuur beschreven en leest u hoe iframes, frames en de sandboxbridge worden gebruikt voor het instellen van op HTML gebaseerde toepassingen en hoe u HTML-inhoud veilig kunt integreren in op SWF gebaseerde toepassingen.
De runtime past regels toe en biedt mechanismen voor het verhelpen van mogelijke beveiligingsproblemen in HTML en JavaScript. Hierbij worden altijd dezelfde regels toegepast, ongeacht of uw toepassing hoofdzakelijk in JavaScript is geschreven of dat u de HTML- en JavaScript-inhoud in een SWF-toepassing laadt. Inhoud in de sandbox van een toepassing en inhoud in de sandbox die niet van een toepassing is, hebben verschillende rechten. Wanneer inhoud in een iframe of frame wordt geladen, biedt de runtime een veilig
sandboxbridge
-mechanisme, waardoor de inhoud van het frame of iframe veilig kan communiceren met de inhoud van de toepassingsbeveiligingssandbox.
De AIR SDK bevat drie klassen voor het renderen van HTML-inhoud.
De HTMLLoader-klasse verschaft nauwe integratie tussen JavaScript-code en de AIR API's.
De StageWebView-klasse is een HTML-renderingklasse die slechts in zeer beperkte mate integreert met de AIR-hosttoepassing. Door de StageWebView-klasse geladen inhoud wordt nooit in de beveiligingssandbox van de toepassing geplaatst en kan geen gegevens benaderen of functies aanroepen in de AIR-hosttoepassing. Op bureaubladplatformen gebruikt de StageWebView-klasse de geïntegreerde, op Webkit gebaseerde AIR HTML-engine die ook door de HTMLLoader-klasse wordt gebruikt. Op mobiele platformen gebruikt de StageWebView-klasse het door het besturingssysteem verschafte HTML-controlemiddel. Op mobiele platformen gelden voor de StageWebView-klasse dus dezelfde beveiligingsoverwegingen en en -problemen als voor de webbrowser van het systeem.
De TextField-klasse kan tekenreeksen met HTML-tekst weergeven. Er kan geen JavaScript worden uitgevoerd, maar de tekst kan koppelingen en extern geladen afbeeldingen bevatten.
Zie
JavaScript-beveiligingsfouten voorkomen
voor meer informatie.
Overzicht van het configureren van uw HTML-toepassing
Frames en iframes bieden een handige structuur voor het indelen van HTML-inhoud in AIR. Met frames kunt u zowel gegevens persistent houden als veilig werken met externe inhoud.
Aangezien HTML in AIR zijn normale, op pagina's gebaseerde indeling behoudt, wordt de HTML-omgeving volledig vernieuwd als het bovenste frame van de HTML-inhoud naar een andere pagina 'navigeert'. U kunt frames en iframes gebruiken om gegevenspersistentie in AIR te behouden, ongeveer op dezelfde manier als voor een webtoepassing in een browser. Als u de belangrijkste toepassingsobjecten in het bovenste frame plaatst, persisteren ze tot u het frame naar een nieuwe pagina laat navigeren. Gebruik subframes of -iframes om de overgangsdelen van de toepassing te laden en weer te geven. (Er zijn verschillende manieren om voor gegevenspersistentie te zorgen als aanvulling op of in plaats van frames. Bijvoorbeeld cookies, lokale gedeelde objecten, lokale bestandsopslag, gecodeerde bestandsopslag en lokale databaseopslag.)
Aangezien HTML in AIR ook de normale vage grens tussen uitvoerbare code en gegevens heeft, plaatst AIR inhoud in het bovenste frame van de HTML-omgeving in de toepassingssandbox. Na de gebeurtenis
load
waarbij de pagina wordt geladen, beperkt AIR alle bewerkingen zoals
eval()
waarbij een tekenreeks kan worden geconverteerd naar een uitvoerbaar object. Deze beperking wordt altijd toegepast, zelfs als een toepassing geen externe inhoud laadt. Als HTML-inhoud deze beperkte bewerkingen mag uitvoeren, moet u frames of iframes gebruiken om de inhoud in een niet-toepassingssandbox te plaatsen. (Soms moet inhoud in een onderliggend sandboxframe worden uitgevoerd wanneer wordt gewerkt met JavaScript-toepassingsraamwerken die zijn gebaseerd op de functie
eval()
.) Zie
Codebeperkingen voor de inhoud van verschillende sandboxen
voor de volledige lijst van JavaScript-beperkingen in de toepassingssandbox.
Aangezien HTML in AIR de mogelijkheid behoudt om externe, mogelijk onveilige inhoud te laden, past AIR een 'beleid van zelfde oorsprong' toe om de voorkomen dat de inhoud van een bepaald domein in contact komt met de inhoud van een ander domein. Als u contact tussen de inhoud van de toepassing en de inhoud van een ander domein wilt toestaan, kunt u een bridge creëren die fungeert als interface tussen een hoofd- en een subframe.
Relatie tussen hoofd- en subsandbox creëren
AIR voegt de kenmerken
sandboxRoot
en
documentRoot
toe aan de HTML frame- en iframe-elementen. Met deze kenmerken kunt u de toepassingsinhoud behandelen alsof deze van een ander domein afkomstig is:
Attribuut
|
Beschrijving
|
sandboxRoot
|
De URL waarmee de sandbox en het domein worden bepaald waarin de frame-inhoud wordt geplaatst. Het URL-schema
file:
,
http:
of
https:
moet worden gebruikt.
|
documentRoot
|
De URL waarvan de frame-inhoud moet worden geladen. Het URL-schema
file:
,
app:
of
app-storage:
moet worden gebruikt.
|
In het volgende voorbeeld wordt de inhoud van de sandboxsubdirectory van de toepassing zo geconfigureerd dat deze wordt uitgevoerd in de externe sandbox en het domein www.example.com:
<iframe
src="ui.html"
sandboxRoot="http://www.example.com/local/"
documentRoot="app:/sandbox/">
</iframe>
Bridge tussen hoofd- en een subframes in verschillende sandboxen of domeinen instellen
AIR voegt de eigenschappen
childSandboxBridge
en
parentSandboxBridge
toe aan het
window
-object van een willekeurig subframe. Met deze eigenschappen kunt u bridges definiëren als interfaces tussen een hoofd- en een subframe. Elke bridge gaat in één richting:
childSandboxBridge
- met de eigenschap
childSandboxBridge
kan het subframe een interface toegankelijk maken voor de inhoud van het hoofdframe. Als u een interface toegankelijk wilt maken, stelt u de eigenschap
childSandbox
in op een functie of object in het subframe. Vervolgens hebt u toegang tot het object of de functie vanuit de inhoud van het hoofdframe. In het volgende voorbeeld ziet u hoe een script dat in een subframe wordt uitgevoerd, een object dat een functie en een eigenschap bevat, toegankelijk kan maken voor het hoofdframe:
var interface = {};
interface.calculatePrice = function(){
return .45 + 1.20;
}
interface.storeID = "abc"
window.childSandboxBridge = interface;
Als deze onderliggende inhoud zich bevindt in een iframe waaraan de
id
"child"
is toegewezen, hebt u vanuit de bovenliggende inhoud toegang tot de interface door de eigenschap
childSandboxBridge
van het frame te lezen:
var childInterface = document.getElementById("child").childSandboxBridge;
air.trace(childInterface.calculatePrice()); //traces "1.65"
air.trace(childInterface.storeID)); //traces "abc"
parentSandboxBridge
- met de eigenschap
parentSandboxBridge
kan het bovenliggende frame een interface toegankelijk maken voor de inhoud van het subframe. Als u een interface toegankelijk wilt maken, stelt u de eigenschap
parentSandbox
van het onderliggende frame in op een functie of object in het bovenliggende frame. Vervolgens hebt u toegang tot het object of de functie vanuit de inhoud van het onderliggende frame. In het volgende voorbeeld ziet u hoe een script dat in het bovenliggende frame wordt uitgevoerd, een object dat de functie Save bevat, toegankelijk kan maken voor een onderliggend frame:
var interface = {};
interface.save = function(text){
var saveFile = air.File("app-storage:/save.txt");
//write text to file
}
document.getElementById("child").parentSandboxBridge = interface;
Via deze interface kan de inhoud van het onderliggende frame bijvoorbeeld tekst opslaan in een bestand met de naam save.txt. De inhoud heeft echter geen andere toegang tot het bestandssysteem. Normaliter moet de toepassingsinhoud de kleinst mogelijke interface toegankelijk maken voor andere sandboxen. De onderliggende inhoud kan bijvoorbeeld de functie Save als volgt aanroepen:
var textToSave = "A string.";
window.parentSandboxBridge.save(textToSave);
Als onderliggende inhoud een eigenschap van het object
parentSandboxBridge
probeert in te stellen, genereert de runtime een SecurityError-fout. Als bovenliggende inhoud een eigenschap van het object
childSandboxBridge
probeert in te stellen, genereert de runtime een SecurityError-fout.
Codebeperkingen voor de inhoud van verschillende sandboxen
Zoals beschreven in de inleiding van dit onderwerp,
HTML-beveiliging in Adobe AIR
, dwingt de runtime regels af en biedt deze mechanismen voor het overwinnen van mogelijke zwakheden in de beveiliging in HTML en JavaScript. De desbetreffende beperkingen staan in dit onderwerp. Als code deze beperkte API's probeert op te roepen, geeft de runtime de foutmelding weer dat er in de runtime van Adobe AIR een beveiligingsfout betreffende JavaScript-code in de toepassingsbeveiligingssandbox is opgetreden.
Zie
JavaScript-beveiligingsfouten voorkomen
voor meer informatie.
Beperkingen betreffende het gebruik van de JavaScript-functie eval() en soortgelijke technieken
Voor de HTML-inhoud van de toepassingsbeveiligingssandbox zijn er beperkingen betreffende het gebruik van API's die tekenreeksen dynamisch in programmacode kunnen omzetten nadat de code is geladen (nadat de gebeurtenis
onload
van het element
body
is verzonden en de handlerfunctie
onload
is voltooid). Hierdoor wordt voorkomen dat de toepassing onbedoeld code van niet-toepassingsbronnen (zoals mogelijk onveilige netwerkdomeinen) opneemt (en uitvoert).
Als uw toepassing bijvoorbeeld tekenreeksgegevens van een externe bron gebruikt om naar de eigenschap innerHTML van een DOM-element te schrijven, bevat de tekenreeks mogelijk (JavaScript-) programmacode die onveilige bewerkingen kan uitvoeren. Tijdens het laden van de inhoud is er echter geen risico dat externe tekenreeksen in het DOM-element worden ingevoegd.
Eén beperking betreft het gebruik van de JavaScript-functie
eval()
. Nadat code in de toepassingssandbox is geladen en de gebeurtenishandler onload is verwerkt, kunt u de functie
eval()
slechts met bepaalde beperkingen gebruiken. De volgende regels gelden voor het gebruik van de functie
eval()
nadat
code is geladen uit de toepassingsbeveiligingssandbox:
-
Expressies met literalen zijn toegestaan. Bijvoorbeeld:
eval("null");
eval("3 + .14");
eval("'foo'");
-
Objectliteralen zijn toegestaan, zoals in de volgende situatie:
{ prop1: val1, prop2: val2 }
-
Setter/getters met objectliteralen zijn
niet toegestaan
, zoals in de volgende situatie:
{ get prop1() { ... }, set prop1(v) { ... } }
-
Arrayliteralen zijn toegestaan, zoals in de volgende situatie:
[ val1, val2, val3 ]
-
Expressies met het lezen van eigenschappen zijn
niet toegestaan
, zoals in de volgende situatie:
a.b.c
-
Het oproepen van functies is
niet toegestaan
.
-
Functiedefinities zijn
niet toegestaan
.
-
Het instellen van eigenschappen is
niet toegestaan
.
-
Functieliteralen zijn
niet toegestaan
.
Tijdens het laden van de code, vóór de gebeurtenis
onload
, en tijdens de uitvoering van de gebeurtenishandlerfunctie
onload
gelden deze beperkingen echter niet voor de inhoud van de toepassingsbeveiligingssandbox.
Bij de volgende code bijvoorbeeld treedt een fout op nadat code is geladen:
eval("alert(44)");
eval("myFunction(44)");
eval("NativeApplication.applicationID");
Dynamisch gegenereerde code, zoals bij het oproepen van de functie
eval()
, zou een veiligheidsrisico zijn als deze toegang kreeg tot de toepassingssandbox. Een toepassing kan bijvoorbeeld onbedoeld een tekenreeks uitvoeren die is geladen vanaf een netwerkdomein en schadelijke code bevat. De code kan bijvoorbeeld bestanden op de computer van de gebruiker verwijderen of wijzigen. Of de inhoud van een lokaal bestand doorsturen naar een niet-vertrouwd netwerkdomein.
Dynamische code kan op de volgende manieren worden gegenereerd:
-
door het oproepen van de functie
eval()
;
-
door eigenschappen van het type
innerHTML
of DOM-functies te gebruiken om scripttags in te voegen die een script buiten de toepassingsmap laden;
-
door eigenschappen van het type
innerHTML
of DOM-functies te gebruiken om scripttags in te voegen die inline code bevatten (in plaats van een script te laden via het kenmerk
src
);
-
door het kenmerk
src
voor
script
tags zo in te stellen dat een JavaScript-bestand wordt geladen dat zich buiten de toepassingsmap bevindt;
-
door het URL-schema
javascript
te gebruiken (zoals in
href="javascript:alert('Test')"
);
-
door de functie
setInterval()
of
setTimeout()
te gebruiken, waarbij de eerste parameter (die de functie asynchroon laat uitvoeren) een (te evalueren) tekenreeks en geen functienaam is (zoals in
setTimeout('x = 4', 1000)
);
-
door
document.write()
of
document.writeln()
op te roepen.
Code in de toepassingsbeveiligingssandbox kan tijdens het laden van inhoud alleen deze methoden gebruiken.
Deze beperkingen blokkeren het gebruik van
eval()
met JSON-objectliteralen
niet
. Hierdoor kan de inhoud van uw toepassing met de JSON JavaScript-bibliotheek werken. U kunt echter geen overbelaste JSON-code (met gebeurtenishandlers) gebruiken.
Voor andere Ajax-frameworks en JavaScript-codebibliotheken moet u controleren of de code in het framework of de bibliotheek binnen deze beperkingen betreffende dynamisch gegenereerde code werkt. Als dat niet het geval is, neemt u alle inhoud die gebruikmaakt van het framework of de bibliotheek op in een niet-toepassingsbeveiligingssandbox. Zie
Beperkingen voor JavaScript in AIR
en
Scripting tussen toepassings- en niet-toepassingsinhoud
. Adobe houdt een lijst bij van Ajax-frameworks waarvan bekend is dat ze de toepassingsbeveiligingssandbox ondersteunen. Ga hiervoor naar
http://www.adobe.com/products/air/develop/ajax/features/
.
In tegenstelling tot de inhoud van de toepassingsbeveiligingssandbox kan JavaScript-inhoud van een niet-toepassingsbeveiligingssandbox
wel
de functie
eval()
oproepen om op elk gewenst moment dynamisch gegenereerde code uit te voeren.
Beperkingen betreffende de toegang tot AIR API's (voor niet-toepassingssandboxen)
JavaScript-code in een niet-toepassingssandbox heeft geen toegang tot het object
window.runtime
, zodat deze code geen AIR API's kan uitvoeren. Als de inhoud van een niet-toepassingsbeveiligingssandbox de volgende code oproept, treedt een TypeError-fout op:
try {
window.runtime.flash.system.NativeApplication.nativeApplication.exit();
}
catch (e)
{
alert(e);
}
Het fouttype is TypeError (niet-gedefinieerde waarde) omdat de inhoud van de niet-toepassingssandbox het object
window.runtime
niet herkent en het als een niet-gedefinieerde waarde beschouwt.
Als u runtime-functionaliteit toegankelijk wilt maken voor de inhoud van een niet-toepassingssandbox, gebruikt u een scriptbridge. Zie
Scripting tussen toepassings- en niet-toepassingsinhoud
voor meer informatie.
Beperkingen betreffende het gebruik van XMLHttpRequest-oproepen
HTML-inhoud in de beveiligingssandbox van de toepassing kan niet tegelijkertijd XMLHttpRequest-methoden gebruiken voor het laden van buiten de toepassingssandbox terwijl de HTML-inhoud wordt geladen en tijdens de
onLoad
-gebeurtenis.
De HTML-inhoud van niet-toepassingsbeveiligingssandboxen kan standaard geen JavaScript XMLHttpRequest-object gebruiken om gegevens te laden van andere domeinen dan het domein waarvan de aanvraag afkomstig is. Een tag van het type
frame
of
iframe
kan een kenmerk van het type
allowcrosscomainxhr
bevatten. Als u dit kenmerk instelt op een waarde die niet leeg is, kan de inhoud van het frame of iframe het Javascript XMLHttpRequest-object gebruiken om gegevens te laden uit andere domeinen dan het domein van de code waarvan de aanvraag afkomstig is:
<iframe id="UI"
src="http://example.com/ui.html"
sandboxRoot="http://example.com/"
allowcrossDomainxhr="true"
documentRoot="app:/">
</iframe>
Zie
Scripting tussen de inhoud van verschillende domeinen
voor meer informatie.
Beperkingen betreffende het laden van CSS-, frame-, iframe- en img-elementen (voor de inhoud van niet-toepassingssandboxen)
De HTML-inhoud van externe (netwerk-) beveiligingssandboxen kan alleen inhoud van het type CSS,
frame
,
iframe
of
img
uit externe sandboxen (netwerk-URL's) laden.
De HTML-inhoud van lokaal-met-bestandssysteem, lokaal-met-netwerk of lokaal-vertrouwde sandboxen kan alleen inhoud van het type CSS, frame, iframe of
img
uit lokale sandboxen (niet van toepassings- of externe sandboxen) laden.
Beperkingen betreffende het oproepen van de JavaScript-methode window.open()
Als een venster dat door het oproepen van de JavaScript-methode
window.open()
is gemaakt, de inhoud van een niet-toepassingsbeveiligingssandbox weergeeft, begint de titel van het venster met de titel van het hoofdvenster (vanwaaruit het nieuwe venster is geopend), gevolgd door een dubbele punt. U kunt geen code gebruiken om dat deel van de venstertitel buiten het scherm te verplaatsen.
De inhoud van niet-toepassingsbeveiligingssandboxen kan de JavaScript-methode
window.open()
alleen oproepen als reactie op een gebeurtenis die is gestart door een klik met de muisknop of een druk op een toets van het toetsenbord. Hierdoor wordt voorkomen dat niet-toepassingsinhoud vensters creëert die voor bedrog kunnen worden gebruikt (bijvoorbeeld voor phishingaanvallen). Ook kan de gebeurtenishandler voor de muis- of toetsenbordgebeurtenis de methode
window.open()
niet zo instellen dat deze na een vertraging wordt uitgevoerd (bijvoorbeeld door de functie
setTimeout()
op te roepen).
De inhoud van externe (netwerk-) sandboxen kan de methode
window.open()
alleen gebruiken om de inhoud van externe netwerksandboxen te openen. Deze inhoud kan de methode
window.open()
niet gebruiken om de inhoud van de toepassingssandbox of van lokale sandboxen te openen.
Inhoud in de sandbox Lokaal-met-bestandssysteem, de sandbox Lokaal-met-netwerk en de sandbox Lokaal-vertrouwd (zie
Beveiligingssandboxen
) kan de methode
window.open()
alleen gebruiken om de inhoud van lokale sandboxen te openen. Deze inhoud kan
window.open()
niet gebruiken om de inhoud van de toepassingssandbox of van externe sandboxen te openen.
Fouten bij het oproepen van beperkte code
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.
Zie
JavaScript-beveiligingsfouten voorkomen
voor meer informatie.
Sandboxbescherming bij het laden van HTML-inhoud uit een tekenreeks
Met de methode
loadString()
van de klasse HTMLLoader kunt u HTML-inhoud bij de uitvoering maken. De gegevens die u gebruikt als HTML-inhoud kunnen echter beschadigd zijn als de gegevens worden geladen uit een onbeveiligde internetbron. Om deze reden wordt HTML die is gemaakt met behulp van de methode
loadString()
, niet in de toepassingssandbox geplaatst en heeft deze HTML geen toegang tot API's van AIR. U kunt echter wel de eigenschap
placeLoadStringContentInApplicationSandbox
van een HTMLLoader-object instellen op true, zodat HTML die is gemaakt met de methode
loadString()
, in de toepassingssandbox wordt geplaatst. Zie
HTML-inhoud laden vanuit een tekenreeks
voor meer informatie.
|
|
|