HTML-Sicherheit in Adobe AIR

Adobe AIR 1.0 und höher

In diesem Thema wird die HTML-Sicherheitsarchitektur von AIR beschrieben. Sie erfahren, wie Sie Inlineframes (iframes), Frames und die Sandboxbrücke verwenden, um HTML-Anwendungen einzurichten und HTML-Inhalt sicher in SWF-Anwendungen zu integrieren.

Die Laufzeitumgebung erzwingt Regeln und stellt Mechanismen für die Vermeidung möglicher Sicherheitslücken in HTML und JavaScript bereit. Es gelten dieselben Regeln, unabhängig davon, ob Ihre Anwendung hauptsächlich in JavaScript geschrieben ist oder ob Sie die HTML- und JavaScript-Inhalte in eine SWF-basierte Anwendung laden. Inhalte in der Anwendungs-Sandbox und in anwendungsfremden Sicherheits-Sandboxen verfügen über unterschiedliche Berechtigungen. Beim Laden von Inhalten in einen Inlineframe oder Frame stellt die Laufzeitumgebung einen sicheren Sandboxbrücken -Mechanismus bereit, der es dem Inhalt im Inlineframe oder Frame ermöglicht, sicher mit Inhalt in der Anwendungs-Sandbox zu kommunizieren.

Das AIR-SDK bietet drei Klassen zum Rendern von HTML-Inhalt.

Die HTMLLoader-Klasse ermöglicht eine enge Integration zwischen JavaScript-Code und den AIR-APIs.

Die StageWebView-Klasse ist eine HTML-Render-Klasse, die nur sehr eingeschränkte Integration mit der AIR-Hostanwendung bietet. Von der StageWebView-Klasse geladener Inhalt wird nie in der Sicherheits-Sandbox der Anwendung platziert und kann nicht auf Daten zugreifen oder Funktionen aufrufen, die sich in der AIR-Hostanwendung befinden. Auf Desktop-Plattformen verwendet die StageWebView-Klasse die integrierte HTML-Engine von AIR, die auf dem Webkit basiert, das auch von der HTMLLoader-Klasse verwendet wird. Auf mobilen Plattformen verwendet die StageWebView-Klasse die HTML-Steuerung des Betriebssystems. Deshalb weist die StageWebView-Klasse auf mobilen Plattformen dieselben Sicherheitsaspekte und Schwachstellen auf wie der Webbrowser des Systems.

Die TextField-Klasse kann HTML-Textstrings anzeigen. JavaScript kann nicht ausgeführt werden, aber der Text kann Links und aus externen Quellen geladene Bilder enthalten.

Weitere Informationen finden Sie unter Vermeiden von sicherheitsbezogenen JavaScript-Fehlern .

Überblick über die Konfiguration HTML-basierter Anwendungen

Frames und Inlineframes bieten eine praktische Struktur für HTML-Inhalte in AIR. Frames sind eine Möglichkeit, sowohl die Datenkonsistenz zu wahren als auch sicher mit Remote-Inhalten zu arbeiten.

Da HTML in AIR die normale, seitenbasierte Organisation beibehält, wird die HTML-Umgebung vollständig aktualisiert, wenn der obere Frame des HTML-Inhalts zu einer anderen Seite „navigiert“. Sie können Frames und Inlineframes verwenden, um die permanente Datenspeicherung in AIR zu erhalten, so wie für eine Webanwendung, die in einem Browser ausgeführt wird. Definieren Sie Ihre Hauptanwendungsobjekte im obersten Frame, damit sie dauerhaft bestehen, solange Sie nicht zulassen, dass der Frame zu einer neuen Seite navigiert. Verwenden Sie untergeordnete Frames oder Inlineframes, um die Übergangsteile der Anwendung zu laden. (Es gibt verschiedene andere Möglichkeiten, Daten dauerhaft zu speichern, die zusätzlich zu oder anstelle von Frames verwendet werden können. Dazu gehören Cookies, lokale freigegebene Objekte, lokaler Dateispeicher, der verschlüsselte Dateispeicher und lokaler Datenbankspeicher.)

Die Grenze zwischen ausführbarem Code und Daten ist auch bei HTML in AIR verschwommen. Deshalb stellt AIR Inhalt im obersten Frame der HTML-Umgebung in die Anwendungs-Sandbox. Nach dem load -Seitenereignis beschränkt AIR alle Operationen, zum Beispiel eval() , die einen Textstring in eine ausführbares Objekt konvertieren können. Diese Beschränkung wird auch dann erzwungen, wenn eine Anwendung keine Remote-Inhalte lädt. Damit HTML-Inhalt diese eingeschränkten Operationen ausführen kann, müssen Sie Frames oder Inlineframes verwenden, um den Inhalt in einer anwendungsfremden Sandbox zu platzieren. (Die Ausführung von Inhalten in einem untergeordneten Frame in einer Sandbox kann erforderlich sein, wenn bestimmtes JavaScript-Anwendungs-Framework verwendet wird, das auf der eval() -Funktion basiert.) Eine vollständige Liste der Beschränkungen für JavaScript in der Anwendungs-Sandbox finden Sie unter Codebeschränkungen für Inhalt in unterschiedlichen Sandboxen .

Da HTML in AIR die Möglichkeit beibehält, remote, potenziell unsichere Inhalte zu laden, erzwingt AIR eine Richtlinie derselben Herkunft, die verhindert, dass Inhalt in einer Domäne mit Inhalt in einer anderen Domäne interagiert. Um Interaktionen zwischen Anwendungsinhalten und Inhalten in anderen Domänen zuzulassen, können Sie eine „Brücke“ als Schnittstelle zwischen einem übergeordneten und einem untergeordnetem Frame einrichten.

Einrichten einer hierarchischen Sandbox-Beziehung

AIR fügt den frame- und iframe-HTML-Elementen die Attribute sandboxRoot und documentRoot hinzu. Mithilfe dieser Attribute kann Anwendungsinhalt so behandelt werden, als käme er aus einer anderen Domäne:

Attribut

Beschreibung

sandboxRoot

Die URL, mit der die Sandbox und die Domäne, in der der Frame-Inhalt platziert wird, bestimmt wird. Es muss das URL-Schema file: , http: oder https: verwendet werden.

documentRoot

Die URL, von der der Frame-Inhalt geladen wird. Es muss das URL-Schema file: , app: oder app-storage: verwendet werden.

Im folgenden Beispiel wird Inhalt im Sandbox-Unterverzeichnis der Anwendung für die Ausführung in der Remote-Sandbox und der Domäne www.example.com domain bestimmt:

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

Einrichten einer Brücke zwischen übergeordneten und untergeordneten Frames in unterschiedlichen Sandboxen oder Domänen

AIR fügt die childSandboxBridge -Eigenschaft und die parentSandboxBridge -Eigenschaft dem window -Objekt jedes untergeordneten Frames hinzu. Mit diesen Eigenschaften können Sie Brücken definieren, die als Schnittstellen zwischen einem übergeordneten und einem untergeordneten Frame dienen. Jede Brücke verläuft in eine Richtung:

childSandboxBridge – Die childSandboxBridge -Eigenschaft ermöglicht dem untergeordneten Frame, eine Schnittstelle zum Inhalt im übergeordneten Frame zu öffnen. Um eine Schnittstelle zu öffnen, stellen Sie die childSandbox -Eigenschaft für eine Funktion oder ein Objekt im untergeordneten Frame ein. Sie können dann vom Inhalt im übergeordneten Frame aus auf das Objekt oder die Funktion zugreifen. Im folgenden Beispiel wird veranschaulicht, wie ein Skript, das in einem untergeordneten Frame ausgeführt wird, ein Objekt, das eine Funktion und eine Eigenschaft enthält, für den übergeordneten Frame öffnen kann:

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

Wenn sich dieser untergeordnete Inhalt in einem Inlineframe mit der zugewiesenen id "child" befindet, können Sie vom übergeordneten Inhalt auf die Schnittstelle zugreifen, indem Sie die childSandboxBridge -Eigenschaft des Frames lesen:

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

parentSandboxBridge – Die parentSandboxBridge -Eigenschaft ermöglicht dem übergeordneten Frame, eine Schnittstelle zum Inhalt im untergeordneten Frame zu öffnen. Um eine Schnittstelle zu öffnen, stellen Sie die parentSandbox -Eigenschaft für eine Funktion oder ein Objekt im übergeordneten Frame ein. Sie können dann vom Inhalt im untergeordneten Frame aus auf das Objekt oder die Funktion zugreifen. Im folgenden Beispiel wird veranschaulicht, wie ein Skript, das im übergeordneten Frame ausgeführt wird, ein Objekt, das eine save-Funktion enthält, für einen untergeordneten Frame öffnen kann:

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

Unter Verwendung dieser Schnittstelle könnte Inhalt im untergeordneten Frame Text in einer Datei mit dem Namen „save.txt“ speichern. Der Inhalt hätte jedoch ansonsten keinen Zugriff auf das Dateisystem. Im Allgemeinen sollte Anwendungsinhalt die kleinstmögliche Schnittstelle zu anderen Sandboxen öffnen. Der untergeordnete Inhalt könnte die save-Funktion wie folgt aufrufen:

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

Wenn untergeordneter Inhalt versucht, eine Eigenschaft des parentSandboxBridge -Objekts festzulegen, gibt die Laufzeitumgebung eine SecurityError-Ausnahme aus. Wenn übergeordneter Inhalt versucht, eine Eigenschaft des childSandboxBridge -Objekts festzulegen, gibt die Laufzeitumgebung eine SecurityError-Ausnahme aus.

Codebeschränkungen für Inhalt in unterschiedlichen Sandboxen

Wie am Anfang dieses Abschnitts unter HTML-Sicherheit in Adobe AIR erwähnt, erzwingt die Laufzeitumgebung Regeln und stellt Mechanismen bereit, um mögliche Sicherheitslücken in HTML und JavaScript zu schließen. Im vorliegenden Abschnitt werden diese Beschränkungen beschrieben. Wenn Code versucht, diese beschränkten APIs aufzurufen, gibt die Laufzeitumgebung einen Fehler mit der Meldung „Adobe AIR runtime security violation for JavaScript code in the application security sandbox“ (Adobe AIR-Laufzeitumgebung: Sicherheitsverletzung bei JavaScript-Code in der Sicherheits-Sandbox der Anwendung) aus.

Weitere Informationen finden Sie unter Vermeiden von sicherheitsbezogenen JavaScript-Fehlern .

Beschränkungen bei Verwendung der JavaScript-Funktion eval() und ähnlicher Techniken

Für HTML-Inhalt in der Sicherheits-Sandbox der Anwendung gelten Beschränkungen für die Verwendung von APIs, die Strings dynamisch in ausführbaren Code umwandeln können, nachdem der Code geladen wurde (nachdem das onload -Ereignis des body -Elements ausgelöst und die Ausführung der onload -Prozedurfunktion beendet wurde). Auf diese Weise wird verhindert, dass die Anwendung ungewollt Code aus anderen Quellen als der Anwendung (zum Beispiel von potenziell unsicheren Netzwerkdomänen) einfügt und ausführt.

Wenn Ihre Anwendung zum Beispiel Stringdaten von einer Remote-Quelle verwendet, um in die innerHTML-Eigenschaft eines DOM-Elements zu schreiben, könnte der String ausführbaren (JavaScript-)Code enthalten, der unsichere Operationen ausführen könnte. Während der Inhalt geladen wird, besteht jedoch kein Risiko, dass Remote-Strings in das DOM geschrieben werden.

Eine Beschränkung besteht für die Verwendung der JavaScript-Funktion eval() . Nachdem Code in die Anwendungs-Sandbox geladen und die onload-Ereignisprozedur verarbeitet wurde, können Sie die eval() -Funktion nur eingeschränkt verwenden. Die folgenden Regeln gelten für die Verwendung der eval() -Funktion nachdem Code aus der Anwendungs-Sandbox geladen wurde:

  • Ausdrücke, die Literale beinhalten, sind zulässig. Zum Beispiel:

    eval("null"); 
    eval("3 + .14"); 
    eval("'foo'");
  • Objektliterale sind zulässig, wie im Folgenden:

    { prop1: val1, prop2: val2 }
  • Set-/Get-Methoden für Objektliterale sind unzulässig , wie im Folgenden:

    { get prop1() { ... }, set prop1(v) { ... } }
  • Arrayliterale sind zulässig, wie im Folgenden:

    [ val1, val2, val3 ]
  • Ausdrücke, die Eigenschaften beinhalten, sind unzulässig , wie im Folgenden:

    a.b.c
  • Der Funktionsaufruf ist unzulässig .

  • Funktionsdefinitionen sind unzulässig .

  • Das Einstellen von Eigenschaften ist unzulässig .

  • Funktionsliterale sind unzulässig .

Während der Code geladen wird, vor dem onload -Ereignis, und während der Ausführung der onload -Ereignisprozedurfunktion, gelten diese Beschränkungen für Inhalte in der Sicherheits-Sandbox der Anwendung jedoch nicht.

Nachdem der Code geladen wurde, führt der folgende Code zum Beispiel dazu, dass die Laufzeitumgebung eine Ausnahme ausgibt:

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

Dynamisch generierter Code, wie zum Beispiel der beim Aufrufen der eval() -Funktion generierte Code, würde ein Sicherheitsrisiko darstellen, wenn er innerhalb der Anwendungs-Sandbox zulässig wäre. Eine Anwendung könnte zum Beispiel unbeabsichtigt einen String ausführen, der aus einer Netzwerkdomäne geladen wurde und schädlichen Code enthält. Dieser Code könnte beispielsweise dazu führen, dass Dateien auf dem Computer des Benutzer gelöscht oder verändert werden. Es wäre auch möglich, dass der Code den Inhalt einer lokalen Daten an eine nicht vertrauenswürdige Netzwerkdomäne weitergibt.

Dynamischer Code kann auf folgende Weise generiert werden:

  • Aufrufen der eval() -Funktion.

  • Verwenden von innerHTML -Eigenschaften oder DOM-Funktionen, um Skript-Tags einzufügen, die ein Skript außerhalb des Anwendungsverzeichnisses laden.

  • Verwenden von innerHTML -Eigenschaften oder DOM-Funktionen, um Skript-Tags einzufügen, die Inlinecode enthalten (anstatt ein Skript über das src -Attribut zu laden).

  • Einstellen des src -Attributs für ein script -Tag, um eine JavaScript-Datei zu laden, die sich außerhalb des Anwendungsverzeichnisses befindet.

  • Verwenden des javascript -URL-Schemas (wie in href="javascript:alert('Test')" ).

  • Verwenden der setInterval() - oder setTimout() -Funktion, wenn der erste Parameter (der die asynchrone Ausführung der Funktion festlegt) ein (zu evaluierender) String ist anstatt ein Funktionsname (wie in setTimeout('x = 4', 1000) ).

  • Aufrufen der document.write() - oder document.writeln() -Methode.

Code in der Anwendungs-Sandbox kann diese Methoden nur verwenden, während Inhalt geladen wird.

Diese Beschränkungen verhindern nicht die Verwendung von eval() mit JSON-Objektliteralen. Auf diese Weise kann Ihr Anwendungsinhalt mit der JSON-JavaScript-Bibliothek arbeiten. Sie können jedoch keinen überladenen JSON-Code (mit Ereignisprozeduren) verwenden.

Überprüfen Sie bei anderen Ajax-Frameworks und JavaScript-Codebibliotheken, ob der Code im Framework bzw. in der Bibliothek im Rahmen dieser Beschränkungen für dynamisch generierten Code funktioniert. Ist dies nicht der Fall, platzieren Sie alle Inhalte, die das Framework oder die Bibliothek verwenden, in einer anwendungsfremden Sandbox. Einzelheiten finden Sie unter Einschränkungen für JavaScript in AIR und Skripterstellung zwischen Anwendungsinhalt und anwendungsfremdem Inhalt . Adobe unterhält eine Liste von Ajax-Frameworks, die die Anwendungs-Sandbox unterstützen, unter http://www.adobe.com/de/products/air/develop/ajax/features/ .

Anders als Inhalt in der Anwendungs-Sandbox kann JavaScript-Inhalt in einer anwendungsfremden Sandbox jederzeit die eval() -Funktion aufrufen, um dynamisch generierten Code auszuführen.

Beschränkungen für den Zugriff auf AIR-APIs (für anwendungsfremde Sandboxen)

JavaScript-Code in einer anwendungsfremden Sandbox hat keinen Zugriff auf das window.runtime -Objekt und der Code kann keine AIR-APIs ausführen. Wenn Inhalt in einer anwendungsfremden Sandbox den folgenden Code aufruft, gibt die Anwendung eine TypeError-Ausnahme aus:

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

Der Ausnahmetyp ist TypeError (nicht definierter Wert), da Inhalt in der anwendungsfremden Sandbox das window.runtime -Objekt nicht erkennt und es deshalb als nicht definierten Wert betrachtet.

Sie können Funktionen der Laufzeitumgebung für Inhalt in einer anwendungsfremden Sandbox öffnen, indem Sie eine Skriptbrücke verwenden. Weitere Informationen finden Sie unter Skripterstellung zwischen Anwendungsinhalt und anwendungsfremdem Inhalt .

Beschränkungen bei der Verwendung von XMLHttpRequest-Aufrufen

HTML-Inhalt in der Anwendungs-Sandbox kann keine synchronen XMLHttpRequest-Methoden verwenden, um Daten von außerhalb der Anwendungs-Sandbox zu laden, während der HTML-Inhalt geladen wird und während ein onLoad -Ereignis auftritt.

Standardmäßig ist es für HTML-Inhalt in anwendungsfremden Sandboxen nicht zulässig, mit dem JavaScript-XMLHttpRequest-Objekt Daten aus anderen Domänen als der aufrufenden Domäne zu laden. Ein frame - oder iframe -Tag kann ein allowcrosscomainxhr -Attribut beinhalten. Wenn dieses Attribut auf einen anderen Wert als null eingestellt ist, kann der Inhalt im Frame oder Inlineframe das XMLHttpRequest-Objekt aus JavaScript verwenden, um Daten auch aus Domänen zu laden, bei denen es sich nicht um die Domäne des Codes handelt, der die Anforderung aufruft:

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

Weitere Informationen finden Sie unter Skripterstellung zwischen Inhalten in unterschiedlichen Domänen .

Beschränkungen beim Laden von CSS-, frame-, iframe- und img-Elementen (für Inhalte in anwendungsfremden Sandboxen)

HTML-Inhalte in Remote-Sandboxen (Netzwerk-Sandboxen) können nur CSS-, frame -, iframe - und img -Inhalt aus Remote-Sandboxen (von Netzwerk-URLs) laden.

HTML-Inhalt in „local-with-filesystem“-, „local-with-networking“- oder „local-trusted“-Sandboxen kann nur CSS-, frame -, iframe- und img-Inhalte aus lokalen Sandboxen (nicht aus der Anwendungs-Sandbox oder aus Remote-Sandboxen) laden.

Beschränkungen beim Aufrufen der JavaScript-window.open()-Methode

Wenn ein Fenster, das über einen Aufruf der JavaScript-Methode window.open() erstellt wurde, Inhalt aus einer anwendungsfremden Sandbox anzeigt, beginnt der Titel des Fensters mit dem Titel des Hauptfensters (des aufrufenden Fensters), gefolgt von einem Doppelpunkt. Sie können diesen Teil des Fenstertitels nicht mithilfe von Code vom Bildschirm bewegen.

Inhalt in anwendungsfremden Sicherheits-Sandboxen kann die JavaScript-Methode window.open() nur als Antwort auf ein Ereignis, das durch eine Benutzerinteraktion mit Maus oder Tastatur ausgelöst wurde, erfolgreich aufrufen. Auf diese Weise wird verhindert, dass anwendungsfremder Inhalt Fenster erstellt, die möglicherweise in betrügerischer Absicht verwendet werden (zum Beispiel für Phishing-Angriffe). Außerdem kann die Ereignisprozedur für Maus- und Tastaturereignisse nicht festlegen, dass die window.open() -Methode mit Verzögerung ausgeführt wird (zum Beispiel durch Aufrufen der setTimeout() -Funktion).

Inhalt in Remote-Sandboxen (Netzwerk-Sandboxen) kann die window.open() -Methode nur verwenden, um Inhalt in Remote-Netzwerk-Sandboxen zu öffnen. Dieser Inhalt kann die window.open() -Methode nicht zum Öffnen von Inhalten in der Anwendungs-Sandbox oder in lokalen Sandboxen verwenden.

Inhalt in den Sandboxen „local-with-filesystem“, „local-with-networking“ oder „local-trusted“ (siehe Sicherheits-Sandboxen ) kann die window.open() -Methode nur zum Öffnen von Inhalten in lokalen Sandboxen verwenden. Dieser Inhalt kann die window.open() -Methode nicht zum Öffnen von Inhalten in der Anwendungs-Sandbox oder in Remote-Sandboxen verwenden.

Fehler beim Aufrufen von beschränktem Code

Wenn Sie Code aufrufen, der aufgrund dieser Sicherheitsregeln in einer bestimmten Sandbox nicht verwendet werden darf, gibt die Laufzeitumgebung einen JavaScript-Fehler aus: "Adobe AIR-Laufzeitumgebung: Sicherheitsverletzung bei JavaScript-Code in der Sicherheits-Sandbox der Anwendung."

Weitere Informationen finden Sie unter Vermeiden von sicherheitsbezogenen JavaScript-Fehlern .

Sandbox-Schutz beim Laden von HTML-Inhalten aus einem String

Mit der loadString() -Methode der HTMLLoader-Klasse können Sie HTML-Inhalt zur Laufzeit erstellen. Daten, die Sie als HTML-Inhalt verwenden, können jedoch schadhaft sein, wenn die Daten aus einer unsicheren Internetquelle geladen werden. Aus diesem Grund wird mit der loadString() -Methode erstellter HTML-Inhalt standardmäßig nicht in der Anwendungs-Sandbox abgelegt und hat keinen Zugriff auf AIR-APIs. Sie können jedoch die placeLoadStringContentInApplicationSandbox -Eigenschaft eines HTMLLoader-Objekts auf „true“ einstellen, um mit der loadString() -Methode erstellten HTML-Inhalt in der Anwendungs-Sandbox zu platzieren. Weitere Informationen finden Sie unter Laden von HTML-Inhalten aus einem String .