Windows Dev Center

Entwickeln von sicheren Apps

Windows Store-Apps mit JavaScript ermöglichen es Entwicklern, die Vielseitigkeit und Ausdruckskraft von Webtechnologien mit einer breiten Palette an leistungsstarken APIs zu kombinieren, die in der Windows-Runtime verfügbar sind. Diese Apps bieten die volle Leistungsstärke herkömmlicher systemeigener Anwendungen und müssen auch genauso sicher sein. Glücklicherweise wurde bei der Entwicklung der Plattform bereits an die Sicherheit gedacht, sodass einige "Schutzschilde" vorhanden sind, die in Kombination mit bewährten Methoden die Entwicklung von sicheren Apps deutlich erleichtern.

Allgemeine Datenquellen

Windows Store-Apps können auf das gesamte Spektrum an Datenquellen zugreifen, die heutzutage im Internet verfügbar sind. Jede dieser Datenquellen muss von Entwicklern hinsichtlich der Sicherheit berücksichtigt und stets validiert werden, um sicherzustellen, das schadhafte Skripte oder andere gefährliche Inhalte die App nicht gefährden können.

Sie müssen sogar Daten prüfen, die von vertrauenswürdigen Quellen, wie einem Back-End-Webdienst, stammen und schadhaften Code ggf. entfernen. Die Daten könnten beim Transport verändert worden sein, oder der Back-End-Webdienst selbst wurde möglicherweise verfälscht. Prüfen Sie alle Daten, die von der App aus dem Netzwerk empfangen werden, um die Sicherheit der App zu gewährleisten und die Benutzer zu schützen.

Der erste Schritt zu mehr Sicherheit ist es, die Punkte zu ermitteln, an denen Daten in die App strömen. Im Folgenden sind einige allgemeine Datenquellen aufgeführt, die Ihre App gefährden können:

Dies sind nur einige wenige Beispiel für nicht vertrauenswürdige Datenquellen. Wie oben bereits angedeutet, besteht der erste Schritt zum Absichern Ihrer App in der Aufnahme des Bestands von Daten, die aus dem Netzwerk stammen.

Sicherheitskontexte und Skriptfilterung

Die Infrastruktur für Windows Store-Apps mit JavaScript wurde so ausgelegt, dass Entwickler allgemeine Sicherheitsprobleme, die einen unsicheren Umgang mit nicht vertrauenswürdigen Daten zur Folge haben können, von Anfang an vermeiden können. Ein neues Feature, das zu erhöhter Sicherheit beitragen kann, ist die Unterstützung von lokalen Kontexten und Webkontexten. Diese Kontexte ermöglichen es Entwicklern, ihre Apps von Beginn an so auszulegen, dass sie nicht vertrauenswürdige Inhalte, wie ein Remote-JavaScript, von vertrauenswürdigem Code und vertrauenswürdigen Daten, die Teil des App-Pakets sind, trennt.

Bei der standardmäßigen Frameisolation werden die Webkontexte von den lokalen Kontexten getrennt. Dabei werden die Kontexte anhand des Ursprungs der Inhalte automatisch bestimmt. So werden beispielsweise Inhalte, die über das Protokoll ms-appx:// weitergegeben werden, automatisch in einen lokalen Kontextframe geladen, während Remotewebinhalte, die von einem iframe-Element geladen werden, stets in einen Webkontext geladen werden. Die beiden Kontexte weisen unterschiedliche Sicherheitseigenschaften und Zugriffsebenen auf (siehe Features und Einschränkungen nach Kontext). Während die beiden Kontexte unterschiedliche Zugriffsebenen aufweisen, wird dank der postMessage-Infrastruktur eine bequeme Kommunikation innerhalb von Frames ermöglicht.

Mit der automatischen Skriptfilterung der DOM-Methoden werden alle dynamischen Inhalte, die als unsicher eingestuft werden, verworfen. So wird verhindert, dass diese Inhalte in das DOM eindringen, während unschädliche Markups intakt bleiben. Wenn der Inhalt einem bestehenden DOM-Element hinzugefügt werden soll, können dafür die Eigenschaften innerText oder outerText ohne Sicherheitsbedenken verwendet werden.

Sicherheitswarnung:  Beachten Sie, dass die automatische Skriptfilterung nicht angewendet wird, wenn Sie innerText und outerText verwenden, um den Text eines script-Elements festzulegen.

Obwohl die automatische Skriptfilterung bereits einen großartigen "Schutzschild" bietet, der den Benutzer vor unerwarteten Angriffen schützt, belassen Sie es nicht bei dieser einen Schutzmaßnahme für Ihre App. Wenn die automatische Skriptfilterung Inhalte blockiert, wird ein Fehler ausgegeben, wodurch das Benutzererlebnis beeinträchtigt werden kann. Des Weiteren verwenden Bibliotheken von Drittanbietern, die mit Daten arbeiten, möglicherweise APIs, die nicht gefiltert werden, was zu Sicherheitsproblemen führen kann. Es ist eine bewährte Methode, nicht auf die automatische Skriptfilterung als einziger Sicherheitsmaßnahme zu vertrauen, sondern innerhalb des Codes proaktiv zu filtern. Ihre App ist am sichersten, wenn nicht vertrauenswürdige Daten explizit gefiltert werden.

Validieren des Ursprungs von invokeScriptAsync - und postMessage-Daten

Die WebView (XAML)- und x-ms-webview (HTML)-Steuerelemente verfügen über Methoden, die der postMessage-Methode für ein iframe ähneln, die kontextübergreifende Kommunikation ermöglicht. Die Methoden InvokeScriptAsync (XAML) und invokeScriptAsync (HTML) sind der bevorzugte Weg, Daten zwischen lokalen Kontexten und Webkontexten in einer Windows Store-App zu übertragen.

Die Methode postMessage ist der bevorzugte Weg, Daten zwischen lokalen Kontexten und Webkontexten in einer Windows Store-App mit JavaScript zu übertragen. Anstatt das Skriptelement zu verwenden oder die App über mehrere Domänen zu verteilen, um eine Hybridanwendung zu erstellen (Apps, die Daten aus unterschiedlichen Quellen im Internet in sich vereinen), verwenden Sie die Methode postMessage. Dank der Frame-basierten Trennung von lokalen Quellen und Remotequellen können Entwickler Remoteinhalte, wie Karten oder Werbung, einbinden, wobei der Dokument- und Ressourcenzugriff anhand der Same-Origin-Policy (auf eine Quelle beschränkter Zugriff) stets isoliert bleibt.

Für die sichere Verwendung der Methoden postMessage und invokeScriptAsync zum Übergeben von Nachrichten zwischen lokalen Dokumenten und Remotedokumenten prüfen Sie den Ursprung einer postMessage oder invokeScriptAsync-Antwort, bevor die Daten verwendet werden. Dies ist erforderlich, da viele Apps über mehrere Remote-iframe- oder WebView-Elemente verfügen, die alle aus unterschiedlichen Quellen stammen und unterschiedlich vertrauenswürdig sind. In der Regel verwendet eine App eine einzelne onmessage-Handlerfunktion für jede Seite, die Nachrichten von allen auf dieser Seite enthaltenen iframe- oder WebView-Elementen verarbeitet.

In diesem Beispiel ist das Aufrufen der invokeScriptAsync (HTML)-Methode dargestellt.


// The application is calling for a specific function inside of the webview
var asyncOp = webView.invokeScriptAsync(“startAnimation”, “500”);
    
asyncOp.oncomplete = function(e){
	// Even though the risk is less with the invokeScript message
	// still make sure not to use eval on the return value.
}

asyncOp.start();



In diesem Beispiel ist das Aufrufen der InvokeScriptAsync (XAML)-Methode dargestellt.


async void webview_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
    var operation = await webview.InvokeScriptAsync("startAnimation", new string[] { "500" });

    if (operation == "success")
    {
        // Handle the message.
    }
} 


Zur Verbesserung der Sicherheit der WebView-Steuerelemente haben wir die Verwendung der window.external.notify()-Funktion mithilfe von WebView-Inhalt eingeschränkt. Diese Einschränkungen verhindern, dass Nachrichten mit nicht vertrauenswürdigem oder manipuliertem Inhalt gesendet werden, die ohne Überprüfung durch den Host ausgeführt werden. Eine der folgenden Bedingungen muss erfüllt sein, damit Inhalt als Benachrichtigung gesendet werden kann:

  • Die Quelle der Seite wurde mithilfe von NavigateToString, NavigateToStream oder ms-appx-web:/// aus dem lokalen System übermittelt.
  • Die Quelle der Seite wird mithilfe https:// übermittelt, und der Domänenname der Website ist im Abschnitt Inhalts-URIs des App-Paketmanifests aufgeführt.
Beispiel:

webview.addEventListener("MSWebViewScriptNotify", handleScriptNotifyEvents);
function handleScriptNotifyEvents(e) {
        if (e.callingUri === "https://msgnotify.example.net/") {
            if(e.value === "msg1")
            {
                // Process the message.);
            }
        }
    }


In dem Beispiel unten sehen Sie zwei Versionen eines onmessage-Handlers: Die erste Version ist nicht sicher, wohingegen die zweite Version sicher ist.


// This message handler is not secure because it does not implement an origin check
window.addEventListener('message', function (e) { 
    div.innerHTML = window.toStaticHTML(e.data); 
}, false);

// Secure message handler, validates message domain origin 
window.addEventListener('message', function (e) {
    if (e.origin === 'http://data.contoso.com') { 
        div.innerHTML = window.toStaticHTML(e.data); 
    }
}, false);


In den meisten Fällen möchte eine App Nachrichten von einem oder zwei iframe-Elementen zulassen, die Kartenkoordinaten oder sonstige legitime Hybridinhalte senden, während sie Nachrichten von nicht vertrauenswürdigen Entitäten, wie Werbung oder Kommentarstreams, verwirft. Das Filtern von Nachrichten nach deren Ursprung ist eine großartige Möglichkeit, die Angriffsfläche einer App zu verringern und sicherzustellen, dass nicht vertrauenswürdige Daten verworfen werden. Stellen Sie sicher, dass Daten immer geprüft werden, wenn ein onmessage-Ereignis verarbeitet wird.

Automatische Skriptfilterung

Führen Sie immer eine Skriptfilterung und Validierung von Daten aus nicht vertrauenswürdigen Quellen aus. Die Art und Weise, wie Sie Daten validieren, hängt davon ab, wofür die Daten verwendet werden. Verwenden Sie DOM-APIs, die dynamische Elemente ignorieren, um dem DOM einfache, statische Daten hinzuzufügen. Mit diesem Ansatz können Sie den Inhalt sicher anzeigen, da jegliche Skriptelemente oder dynamischen Elemente in den Daten als einfacher Text angezeigt und nicht als Code interpretiert werden. Sie können Methoden wie createTextNode verwenden, um ein Element mit nicht vertrauenswürdigen Daten weiterzugeben. Das Element kann dann dem DOM hinzugefügt werden, indem die Methode appendChild oder importNode aufgerufen wird. Wenn der Inhalt einem bestehenden DOM-Element hinzugefügt werden soll, können dafür die Eigenschaften innerText oder outerText ohne Sicherheitsbedenken verwendet werden.

In diesem Beispiel werden dynamische Inhalte auf unsichere Weise hinzugefügt.



// Do not use this code.
// Avoid adding untrusted dynamic content
// Unsafe method 1
var myDiv = document.createElement("div");
myDiv.innerHTML = xhr.responseText 
document.body.appendChild(myDiv);

// Unsafe method 2
document.writeln(xhr.responseText);


In diesem Beispiel werden die dynamischen Inhalte auf sichere Weise hinzugefügt.



// Forcing untrusted content into static text is safe

// method 1
var myDiv = document.createElement("div");
myDiv.innerText = xhr.responseText 
document.body.appendChild(myDiv);

// method 2
var myData = document.createTextNode(xhr.responseText);
document.body.appendChild(myData);

// method3
var oDiv = document.getElementById("div1");
oDiv.outerText = xhr.responseText;



Wenn die nicht vertrauenswürdigen Daten Markups enthalten, verwenden Sie die DOM-Methode window.toStaticHTML, um unsichere Markups herauszufiltern und dabei sichere Daten intakt zu belassen.


// The untrusted data contains unsafe dynamic content
var unTrustedData = "<img src='http://www.contoso.com/logo.jpg' on-click='calltoUnsafeCode();'/>";

// Safe dynamic content can be added to the DOM without introducing errors
var safeData = window.toStaticHTML(unTrustedData);

// The content of the data is now 
// "<img src='http://www.contoso.com/logo.jpg'/>" 
// and is safe to add because it was filtered
document.write(safeData);



Umgehen der automatischen Skriptfilterung

DOM-APIs, die es Ihnen ermöglichen dynamische Markups einzufügen, werden automatisch gefiltert. Explizite Ausführungseingaben, wie eval, werden hingegen nicht gefiltert. Sie können die Methode "eval" verwenden, um die automatische Filterung zu umgehen und dynamische Skripte auszuführen, von denen Sie wissen, dass sie sicher sind. Unten sind einige Skriptausführungsmethoden aufgeführt, die nicht automatisch vom System nach unsicheren Inhalten gefiltert werden:

Da das System diese Methoden nicht automatisch filtert, verwenden Sie die Methoden nicht zum Ausführen von nicht vertrauenswürdigen Daten, ohne die Daten vorher selbst gefiltert oder codiert zu haben.

Die API MSApp.execUnsafeLocalFunction bietet eine Funktion zum Umgehen der automatischen Skriptfilterung, der dynamische Markupinhalte im lokalen Kontext in der Regel unterzogen werden. Dies ist dann besonders nützlich, wenn Sie eine Vorlagenbibliothek wie JQuery verwenden möchten, die Markups generiert und daher von der automatischen Filterung beeinträchtigt werden würde.

Wie auch bei der Verwendung der Methode "eval" können bei Verwendung der Methode MSApp.execUnsafeLocalFunction zum Verarbeiten von nicht vertrauenswürdigen Daten Sicherheitsprobleme auftreten. Die Sicherheitsprobleme können dadurch entstehen, dass die Vorlagenbibliotheken möglicherweise intern nicht vertrauenswürdige Daten in das Dokument schreiben. Wenn der Ursprung von Daten in jeglicher Weise zweifelhaft erscheint, verwenden Sie eine Bibliothek mit sicherer Codierung oder die Methode toStaticHTML, um sicherzustellen, dass die Daten von unsicheren Elementen und unsicherem Code befreit werden.

Verwenden von sicheren Parsern

Bei der Webentwicklung ist es üblich und auch gefährlich, in JavaScript die Methode "eval" zu verwenden, um eine lokales JavaScript-Objekt aus einer serverseitigen JavaScript-Object-Notation-Antwort (JSON) zu generieren. Im Beispiel unten wird die Methode "eval" verwendet, um JSON-Daten zu verarbeiten:


<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div id="foo"></div>
    <script type="text/javascript">
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "http://contoso.com/json.js", false);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {

			                 // DO NOT USE, UNSAFE
                    var myObject = eval('(' + xhr.responseTxt + ')');
                }
            }
        };
        xhr.send();
     </script>
</body>
</html>


Ein Sicherheitsproblem kann entstehen, wenn ein Angreifer aktiv lauscht, um die Daten, die Sie an die Methode "eval" übergeben, zu ändern. Verwenden Sie daher anstatt der Methode "eval" die DOM-Methode "JSON.parse", um den JSON-Text in ein Objekt umzuwandeln. Die Methode "JSON.parse" weist jegliche Skripte ab, die keine JSON-Skripte sind und somit einen Angriff darstellen könnten.

In dem Beispiel unten wird die Methode "JSON.parse" anstatt der Methode "eval" verwendet.


<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div id="foo"></div>
    <script type="text/javascript">
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "http://remote-server.com/json.js", false);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    var myObject = JSON.parse(xhr.responseText);
                }
            }
        };
        xhr.send();
     </script>
</body>
</html>
</body>
</html>



Schützen sensibler Daten

Stellen Sie sicher, dass Ihre App sensible Daten ordnungsgemäß verarbeitet. Verwenden Sie stets SSL, wenn sensible Daten mit Remoteservern ausgetauscht werden, um die Benutzerdaten bestmöglich abzusichern. Tools für Angriffe sind weit verbreitet. Gehen Sie davon aus, dass es immer Angreifer geben wird, die vertrauliche Daten von Apps abfangen möchten, in denen kein SSL verwendet wird.

Zusätzlich zum Datenschutz bietet SSL Vorteile hinsichtlich der Integrität der Anwendung. SSL verhindert eine Manipulation durch Angreifer mit JSON oder anderen Netzwerkdatenströmen. Es ist von entscheidender Bedeutung, die Integrität des Datenverkehrs zu schützen, wenn Sie Netzwerkdaten an Windows-Runtime-APIs übergeben, da diese APIs auf das System des Benutzers zugreifen können.

Erzwingen von HTTPS-Verbindungen

Es ist ganz einfach, die Übertragung aller Remoteinhalte über das Secure Hypertext Transfer Protocol (HTTPS) zu erzwingen. Fügen Sie dazu Ihrer Startseite einfach ein HTML-META-Tag wie folgt hinzu:


<meta name="ms-https-connections-only" content="true"/>

Durch Hinzufügen dieses META-Tags wird für jede von HTTPS abweichende Navigation ein Fehler ausgegeben. So wird der Benutzer vor Manipulationen geschützt, wie DNS-Cache-Vergiftung oder ARP-Cache-Spoofing.

Für Entwickler, die keine bestehende PKI-Infrastruktur haben, unterstützen Windows Store-Apps mit JavaScript das Bündeln von privaten Zertifikaten mit dem Anwendungspaket.

Verwenden des Objekts XDomainRequest

Anders als herkömmliche Browser haben lokale Skripte und Markups in Windows Store-Apps mit JavaScript uneingeschränkten, domänenübergreifenden Zugriff auf Webdienste, wenn sie das Objekt XMLHttpRequest verwenden. Standardmäßig sendet das Objekt XMLHttpRequest durch Cookies authentifizierte Anfragen an eine bestimmte Website, wenn das Objekt mit einem Webdienst kommuniziert oder JSON-Daten abruft. Die Verwendung von Cookies zusammen mit domänenübergreifenden Anfragen birgt zwei Sicherheitsrisiken:

  • Wenn die App verfälscht wird, können Angreifer Zugriff auf Cookies für alle Websites erlangen, die für den lokalen Kontext authentifiziert sind.
  • Jeglicher, nicht per SSL geschützter XMLHttpRequest-Datenverkehr kann abgefangen werden.

Verwenden Sie das Objekt XMLHttpRequest aufgrund dieser Sicherheitsrisiken nur, wenn Sie authentifizierten Zugriff benötigen und dann auch nur über eine SSL-Verbindung. Wenn Sie keinen authentifizierten Zugriff benötigen, verwenden Sie stattdessen das Objekt XDomainRequest. Ähnlich wie bei der Verwendung von XMLHttpRequest ermöglicht XDomainRequest ursprungsübergreifenden Datenverkehr, verwendet allerdings keine Cookies oder verweisende Header. Damit wird sowohl die Sicherheit als auch der Datenschutz bei domänenübergreifenden Anfragen erhöht, wodurch auch die gesamte App rundum sicherer wird.

Einschränken von Navigationsdomänen

Die Navigationsdomäne einer App wird im App-Manifest festgelegt, das sich innerhalb des App-Pakets befindet. Das Einschränken der Liste möglicher Navigationsdomänen ist insofern wichtig, als Angreifern keine Möglichkeit eingeräumt wird, um die Anwendungssitzung eines Benutzers zu einer Domäne umzuleiten, die vom Angreifer gesteuert und für Phishingangriffe oder sonstige schadhafte Aktivitäten genutzt werden kann.

Eine einfache Gegenmaßnahme besteht darin, beim Einbinden von URIs auf Platzhalter zu verzichten, da viele Unterdomänen von großen Webdiensten die Möglichkeit bieten, beliebige Seiten oder andere Inhalte zu hosten, was sich ein Angreifer zu Nutze machen könnte. Weitere Informationen finden Sie unter ApplicationContentUriRules.

Verwendung des WebView-Steuerelements wenn möglich

Für das WebView-Steuerelement sind mehr Sicherheitsmaßnahmen eingerichtet als für ein herkömmliches iframe, daher reduziert die Verwendung dieses Steuerelements für das Hosten von Webinhalt das Risiko, dass App-Code durch beliebige Webinhalte beeinträchtigt wird. Die WebView bietet dieselben Sicherheitsfeatures für Windows Store-Apps mit HTML/JavaScript sowie mit XAML. Durch die Verwendung des ApplicationContentUriRules-Elements im Paketmanifest kann ein Entwickler die Kommunikation dem WebView-Steuerelement und der Hosting-App ermöglichen. Zudem sind Methoden für die Kommunikation mit lokalem Inhalt verfügbar. Weitere Informationen zu Kommunikation finden Sie unter Neues in WebView in Windows 8.1 und Verwendung von Blend für Apps und Websites mit HTML x-ms-webview.

Verwenden des HTML5-Attributs "sandbox"

Das HTML5-Attribut iframe sandbox bringt in einem iframe-Element weitere Einschränkungen für die Inhalte mit sich. Obwohl die standardmäßige Umgebung für Windows Store-Apps mit JavaScript bereits einige auf dem Inhaltsursprung basierende Sicherheitsvorkehrungen bietet, wird mit dem Attribut sandbox ein zusätzliches "Schutzschild" bereitgestellt. Dieses Attribut bietet Entwicklern Unterstützung beim Einschränken von nicht vertrauenswürdigen Inhalten innerhalb einer Seite, wie Werbung oder sonstige Inhalte. Durch Hinzufügen des Attributs sandbox können Inhalte:

  • nicht auf das DOM der übergeordneten Seite zugreifen
  • keine Skripte ausführen
  • keine Formulare integrieren
  • keine Cookies lesen oder schreiben
  • nicht auf den lokalen Speicher zugreifen
  • auf lokale SQL-Datenbanken zugreifen

Wenn Sie das Attribut "sandbox" für die Zugriffseinschränkung von Webinhalten auf Ihre App verwenden, wird die Sicherheit Ihrer App deutlich erhöht.

Verwandte Themen

Features und Einschränkungen nach Kontext
Prüfen Sie Ihr Gadget
Anti-Cross Site Scripting Library (Anti-XSS)
postMessage
invokeScriptAsync (HTML)
InvokeScriptAsync (XAML)

 

 

Anzeigen:
© 2015 Microsoft