WebView – native Brücken

OWASP-Kategorie: MASVS-PLATFORM: Plattforminteraktion

Übersicht

Eine native Bridge, manchmal auch als JavaScript-Bridge bezeichnet, ist ein Mechanismus, der die Kommunikation zwischen einer WebView und nativem Android-Code vereinfacht. Dazu wird die Methode addJavascriptInterface verwendet. Dies ermöglicht bidirektionale Kommunikation zwischen dem in WebView ausgeführten JavaScript-Code und dem Android- den Java-Code der Anwendung. Die Methode addJavascriptInterface stellt ein Java-Objekt allen Frames einer WebView zur Verfügung. Jeder Frame kann auf den Objektnamen zugreifen und Methoden darauf aufrufen. Es gibt jedoch keinen Mechanismus, den Ursprung des aufrufenden Frames in WebView verifizieren, was die Sicherheit erhöht da die Vertrauenswürdigkeit der Inhalte unbestimmt ist.

Eine native Bridge kann auch mit HTML-Nachrichtenkanälen implementiert werden, wobei WebViewCompat.postWebMessage oder WebMessagePort.postMessage von Android verwendet wird, um mit dem JavaScript-Window.postMessage zu kommunizieren. WebViewCompat.postWebMessage und WebMessagePort.postMessage kann JavaScript-Nachrichten akzeptieren, die gesendet werden über Window.postMessage, das in WebView ausgeführt wird.

Native Brücken sind mit mehreren Risiken verbunden:

  • JavascriptInterface-basierte Brücken:
    • Mit der addJavascriptInterface-Methode wird ein bereitgestelltes Java-Objekt in jeden Frame der WebView eingefügt, einschließlich iFrames. Das bedeutet, dass sie anfällig für Angriffe böswilliger Dritter ist, die Frames in eine legitime Website einschleusen. Anwendungen, die auf API-Level 16 oder niedriger ausgerichtet sind, sind besonders anfällig für Angriffe, da diese Methode dazu verwendet werden kann, JavaScript die Steuerung der Hostanwendung zu ermöglichen.
    • Nicht vertrauenswürdige, von Nutzern bereitgestellte Inhalte in nativen Bridge-fähigen WebViews wiedergeben ermöglicht Cross-Site-Scripting (XSS)-Angriffe.
  • MessageChannel-basierte Brücken:
    • Da keine Herkunftsüberprüfungen an den Endpunkten von Nachrichtenkanälen durchgeführt werden, werden Nachrichten von allen Absendern akzeptiert, auch von solchen, die schädlichen Code enthalten.
    • Es ist möglich, dass Java versehentlich beliebigem JavaScript ausgesetzt wird.

Positiv beeinflussen

Die Methoden addJavascriptInterface, postWebMessage und postMessage können von böswilligen Akteuren genutzt werden, um von ihnen kontrollierten Code in eine WebView einzuschleusen, zu manipulieren oder darauf zuzugreifen. Dies kann dazu führen, dass Nutzer auf schädliche Websites weitergeleitet werden, das Laden schädlicher Inhalte oder das Ausführen von bösartigem Code auf ihren Geräten, sensible Daten extrahieren oder Berechtigungen ausweiten können.

Risiko: addJavascriptInterface-Risiken

WebView implementiert grundlegende Funktionen eines Browsers wie Seitenrendering, Navigation und JavaScript-Ausführung. WebView kann in einer Anwendung verwendet werden, um Webinhalte als Teil eines Aktivitätslayouts anzuzeigen. Die Implementierung einer nativen Brücke in einem WebView mithilfe der addJavascriptInterface-Methode kann Sicherheitsprobleme wie Cross-Site-Scripting (XSS) verursachen oder es Angreifern ermöglichen, nicht vertrauenswürdige Inhalte über die Benutzeroberfläche einzuschleusen und die Hostanwendung auf unerwünschte Weise zu manipulieren, indem Java-Code mit den Berechtigungen der Hostanwendung ausgeführt wird.

Abwehrmaßnahmen

JavaScript deaktivieren

Rufen Sie in Fällen, in denen WebView kein JavaScript erfordert, setJavaScriptEnabled innerhalb von WebSettings (z. B. während statische HTML-Inhalte angezeigt werden). Standardmäßig ist die Ausführung von JavaScript in WebView deaktiviert.

JavaScript-Schnittstelle beim Laden nicht vertrauenswürdiger Inhalte entfernen

Stellen Sie sicher, dass Objekte aus der JavaScript-Schnittstelle entfernt werden, indem Sie den Aufruf removeJavascriptInterface, bevor nicht vertrauenswürdige Inhalte vom WebView Dies kann beispielsweise in einem Aufruf von shouldInterceptRequest

Kotlin

webView.removeJavascriptInterface("myObject")

Java

webView.removeJavascriptInterface("myObject");

Webinhalte nur über HTTPS laden

Wenn Sie nicht vertrauenswürdige Inhalte laden müssen, achten Sie darauf, dass die WebView Webinhalte über eine verschlüsselte Verbindung lädt. Weitere Informationen finden Sie in unseren Richtlinien zu Kommunikation im Klartext. Verhindern Sie den anfänglichen Seitenaufbau auf unverschlüsselte Verbindungen durch Festlegen von android:usesCleartextTraffic auf false in AndroidManifest-Datei oder HTTP-Traffic in einer Netzwerksicherheit zulassen config verwenden. Weitere Informationen finden Sie in der Dokumentation zu usesCleartextTraffic. Informationen.

XML

<application
    android:usesCleartextTraffic="false">
    <!-- Other application elements -->
</application>

Damit Weiterleitungen und weitere App-Suchanfragen nicht über unverschlüsselten Traffic erfolgen, prüfen Sie in loadUrl oder shouldInterceptRequest, ob das HTTP-Schema verwendet wird:

Kotlin

fun loadSecureUrl(webView: WebView?, url: String?) {
    webView?.let { wv ->  // Ensure valid WebView and URL
        url?.let {
            try {
                val uri = URI(url)
                if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
                    wv.loadUrl(url)
                } else {
                    // Log an error or handle the case where the URL is not secure
                    System.err.println("Attempted to load a non-HTTPS URL: $url")
                }
            } catch (e: Exception) {
                // Handle exception for improper URL format
                System.err.println("Invalid URL syntax: $url")
            }
        }
    }
}

Java

public void loadSecureUrl(WebView webView, String url) {
    if (webView != null && url != null) { // Ensure valid WebView and URL
        try {
            URI uri = new URI(url);
            String scheme = uri.getScheme();
            if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
                webView.loadUrl(url);
            } else {
                // Log an error or handle the case where the URL is not secure
                System.err.println("Attempted to load a non-HTTPS URL: " + url);
            }
        } catch (URISyntaxException e) {
            // Handle exception for improper URL format
            System.err.println("Invalid URL syntax: " + url);
        }
    }
}

Nicht vertrauenswürdige Inhalte validieren

Wenn externe Links in einer WebView geladen werden, validieren Sie sowohl das Schema als auch den Host. (Domains auf die Zulassungsliste setzen). Alle Domains, die nicht auf der Zulassungsliste stehen, müssen vom Standardbrowser.

Keine nicht vertrauenswürdigen Inhalte laden

Laden Sie nach Möglichkeit nur URLs mit streng beschränkten Geltungsbereichen und Inhalte, die der App gehören in WebView importieren.

Vertrauliche Daten nicht offenlegen

Wenn Ihre Anwendung mit einer WebView auf sensible Daten zugreift, sollten Sie die Verwendung des clearCache, um lokal gespeicherte Dateien zu löschen, bevor Sie den JavaScript-Schnittstelle. Sie können auch serverseitige Header wie „no-store“ verwenden, um anzugeben, dass eine Anwendung bestimmte Inhalte nicht im Cache speichern soll.

Vertrauliche Funktionen nicht offenlegen

Wenn für Ihre Anwendung vertrauliche Berechtigungen erforderlich sind oder sie vertrauliche Daten erhebt, achten Sie darauf, dass sie aus dem Code innerhalb der Anwendung aufgerufen wird und dass die Nutzer deutlich über die Datenerhebung informiert werden. Vermeiden Sie die Verwendung von JavaScript-Schnittstellen für sensible Vorgänge oder Nutzerdaten.

Ziel-API-Level 21 oder höher

Eine sichere Möglichkeit, die addJavascriptInterface-Methode zu verwenden, besteht darin, das API-Level auf 21 oder höher auszurichten. So wird sichergestellt, dass die Methode nur aufgerufen wird, wenn sie auf API-Level 21 oder höher ausgeführt wird. Vor API 21 konnte JavaScript mithilfe von Reflexion auf die Öffentlichkeit zugreifen eines injizierten Objekts.


Risiko: Risiken von MessageChannel

Wenn in postWebMessage() und postMessage() keine Herkunftskontrolle vorhanden ist, können Angreifer Nachrichten abfangen oder an native Handler senden.

Abwehrmaßnahmen

Beim Einrichten von postWebMessage() oder postMessage() nur Nachrichten zulassen von vertrauenswürdigen Domains, indem Sie * als Zielursprung vermeiden, die erwartete Absenderdomain explizit angeben.


Ressourcen