Android Coden
Android 4 min lesen

WebView-Sicherheit

WebView öffnet Sicherheitslücken in jeder Android-App. Lerne, wie du JavaScript-Bridge, mixed Content und URLs gezielt absicherst.

Sobald du eine WebView in deine App einbindest, öffnest du ein Fenster zur offenen Web-Welt — und damit potenziell auch zu deren Risiken. Ohne gezielte Härtung kann eine WebView zum Einfallstor für Cross-Site-Scripting, unerwünschte URL-Weiterleitungen oder sogar für den direkten Zugriff auf native App-Funktionen werden. Dieses Kapitel zeigt dir, welche Stellschrauben wirklich zählen und warum du sie von Anfang an richtig setzen musst.

Was ist das?

WebView ist eine in das Android-Framework integrierte Browser-Komponente, mit der du Web-Inhalte direkt innerhalb deiner App darstellst. Sie basiert auf Chromium und bringt eine vollständige Web-Engine mit — inklusive JavaScript-Ausführung, Cookie-Verwaltung und eigenständiger Netzwerkkommunikation.

Genau diese Mächtigkeit macht sie sicherheitskritisch. Eine reine native App führt ausschließlich Code aus, den du selbst geschrieben hast. Eine WebView verarbeitet dagegen potenziell beliebige Web-Inhalte aus dem Netz. Für Angreifer bedeutet das: Wer die geladene URL kontrolliert oder fremden HTML-Code einschleust, kann unter Umständen JavaScript in deiner App-Umgebung ausführen — oder über einen JavaScript-Bridge auf native Android-APIs zugreifen, die weit über das hinausgehen, was eine normale Webseite jemals dürfte.

Im Roadmap-Kontext steht WebView-Sicherheit in der Phase zu Platform APIs und Gerätezugriffen, weil sie exakt an der Grenze zwischen Web und nativem System sitzt. Diese Schnittfläche ist eine der heikelsten im Android-Ökosystem und verdient daher besondere Aufmerksamkeit.

Wie funktioniert es?

WebView-Sicherheit gliedert sich in drei Kernbereiche, die du unabhängig voneinander verstehen und konfigurieren musst.

JavaScript-Bridge

Mit addJavascriptInterface(object, name) machst du ein Kotlin-Objekt aus JavaScript heraus aufrufbar. Das ist für hybride Apps oft notwendig, birgt aber ein erhebliches Risiko: Jede öffentliche Methode des Objekts wird zur JavaScript-API. Seit API-Level 17 muss jede erreichbare Methode explizit mit @JavascriptInterface annotiert sein. Ohne diese Annotation und ohne Mindest-API-Level 17 ist die gesamte App über Java-Reflection angreifbar — das betrifft nicht nur die Bridge-Klasse, sondern theoretisch jedes Objekt im Prozess.

Mixed Content

Mixed Content bezeichnet das Laden unverschlüsselter HTTP-Ressourcen — Bilder, Skripte, Stylesheets — innerhalb einer HTTPS-Seite. Das untergräbt HTTPS strukturell, weil ein Angreifer im Netzwerk die HTTP-Ressource manipulieren kann, ohne das HTTPS-Zertifikat brechen zu müssen. Android steuert dieses Verhalten über WebSettings.mixedContentMode mit drei Optionen: MIXED_CONTENT_NEVER_ALLOW blockiert HTTP-Inhalte in HTTPS-Seiten konsequent, MIXED_CONTENT_ALWAYS_ALLOW erlaubt alles ohne Einschränkung, und MIXED_CONTENT_COMPATIBILITY_MODE bildet das ältere Browser-Verhalten nach. Nur die erste Option ist für produktive Apps akzeptabel.

URL-Validierung

Jede Navigation in der WebView läuft durch WebViewClient.shouldOverrideUrlLoading. Hier entscheidest du, welche URLs die WebView laden darf. Ohne einen eigenen WebViewClient kann Android unbekannte URLs in externen Apps öffnen — oder schlimmer: Links mit intent://-Schemata können native Aktionen auslösen, ohne dass der Nutzer das erwartet oder bemerkt.

In der Praxis

Ein typischer sicherer WebView-Setup in Kotlin sieht so aus:

val settings = binding.webView.settings

settings.javaScriptEnabled = true                              // nur wenn nötig
settings.mixedContentMode = WebSettings.MIXED_CONTENT_NEVER_ALLOW
settings.allowFileAccess = false
settings.allowContentAccess = false

class NativeBridge {
    @JavascriptInterface
    fun postMessage(payload: String) {
        // Einzige aus JS erreichbare Methode
    }
}

binding.webView.addJavascriptInterface(NativeBridge(), "Android")

binding.webView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(
        view: WebView,
        request: WebResourceRequest
    ): Boolean {
        val url = request.url
        return !(url.scheme == "https" && url.host == "meine-domain.de")
    }
}

Zusätzlich solltest du HTTP-Traffic app-weit über die network-security-config unterbinden. Lege dazu res/xml/network_security_config.xml an:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="false" />
</network-security-config>

Verknüpfe die Datei im Manifest mit android:networkSecurityConfig="@xml/network_security_config". Das gilt dann automatisch auch für alle Netzwerkzugriffe aus der WebView heraus.

Typische Stolperfalle: Viele Entwicklerinnen und Entwickler aktivieren javaScriptEnabled = true früh in der Entwicklung und vergessen es danach. Wenn die WebView anschließend auch nutzergenerierte URLs lädt — etwa aus einem Chat oder einem QR-Code-Scanner — entsteht ein klassisches XSS-Risiko. Sobald ein Angreifer JavaScript in die angezeigte Seite einschleusen kann, läuft dieser Code in deiner App-Sandbox, mit Zugriff auf alle registrierten Bridges. Das @JavascriptInterface-Gebot schützt dich nur gegen Reflection-Angriffe, nicht gegen XSS in vertrauenswürdig wirkenden Seiten.

Fazit

WebView-Sicherheit ist kein einmaliger Handgriff, sondern ein Bündel aufeinander abgestimmter Einstellungen: JavaScript gezielt einschalten, Mixed Content blockieren, URLs konsequent validieren und die Bridge auf das absolut Notwendige beschränken. Überprüfe in deinem nächsten Code-Review jeden WebView-Setup der Codebasis — ein einfaches grep -r "javaScriptEnabled\|addJavascriptInterface\|MIXED_CONTENT" macht die kritischsten Stellen sofort sichtbar. Wer diese Einstellungen versteht und bewusst setzt, schützt nicht nur die WebView, sondern die gesamte App und ihre Nutzerinnen und Nutzer.

Quellen (3)
Redaktion

Geschrieben von

Redaktion

Das Redaktionsteam recherchiert und schreibt Artikel zu aktuellen Themen rund um Tech, Lifestyle und Ratgeber.