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.