Catégorie OWASP : MASVS-PLATFORM : interaction avec la plate-forme
Présentation
Un pont natif, parfois appelé pont JavaScript, est un mécanisme qui facilite la communication entre une WebView et le code Android natif, en utilisant la méthode addJavascriptInterface
. Cela permet une communication bidirectionnelle entre le code JavaScript exécuté dans la WebView et le code Java de l'application Android. La méthode addJavascriptInterface
expose un objet Java à tous les cadres d'une WebView. N'importe quel cadre peut accéder au nom de l'objet et appeler des méthodes dessus. Cependant, il n'existe aucun mécanisme permettant à l'application
vérifier l'origine du frame appelant dans WebView, ce qui renforce la sécurité
car la fiabilité du contenu reste indéterminée.
Un pont natif peut également être implémenté avec des canaux de message HTML en utilisant
Android WebViewCompat.postWebMessage
ou
WebMessagePort.postMessage
pour communiquer avec le code JavaScript
Window.postMessage
WebViewCompat.postWebMessage
et WebMessagePort.postMessage
peuvent accepter les messages JavaScript envoyés via Window.postMessage
, qui seront exécutés dans la WebView.
Les ponts natifs présentent plusieurs risques:
- Ponts basés sur JavascriptInterface :
- La méthode
addJavascriptInterface
injecte un objet Java fourni dans chaque frame de la WebView, y compris les iFrames, ce qui signifie qu'il est sensible à une attaque par des tiers malveillants injectant des frames dans un site Web légitime. Les applications ciblant le niveau d'API 16 ou version antérieure sont particulièrement exposées aux attaques, car cette méthode peut être utilisée pour permettre à JavaScript de contrôler l'application hôte. - La réflexion de contenu non fiable fourni par l'utilisateur dans des WebView compatibles avec le pont natif permet les attaques de script intersites (XSS).
- La méthode
- Ponts basés sur MessageChannel :
- L'absence de vérification de l'origine sur les points de terminaison des canaux de messages signifie que les messages seront acceptés par n'importe quel expéditeur, y compris ceux contenant du code malveillant.
- Il est possible d'exposer accidentellement Java à du code JavaScript arbitraire.
Impact
Les méthodes addJavascriptInterface
, postWebMessage
et postMessage
peuvent être
exploitées par des personnes malveillantes pour accéder, manipuler ou injecter le code qu'elles contrôlent
dans une WebView. Cela peut conduire les utilisateurs à
être redirigés vers des sites malveillants,
charger du contenu malveillant ou exécuter du code malveillant sur leurs appareils
peuvent extraire des données sensibles ou procéder à une élévation des privilèges.
Risque : risques liés à addJavascriptInterface
WebView implémente les fonctionnalités de base d'un navigateur, telles que le rendu de la page, la navigation et l'exécution JavaScript. WebView peut être utilisé dans une application
pour afficher du contenu web dans
la mise en page d'une activité. Implémenter une annonce native
dans une WebView à l'aide de la méthode addJavascriptInterface
peut créer
des problèmes de sécurité tels que les scripts intersites (XSS) ou qui permettent aux pirates informatiques de charger
du contenu non approuvé par injection d'interface et manipuler l'hôte
application de manière inattendue, en exécutant du code Java avec les autorisations
de votre application hôte.
Stratégies d'atténuation
Désactiver JavaScript
Dans les cas où WebView ne nécessite pas JavaScript, n'appelez pas
setJavaScriptEnabled
dans WebSettings
(par exemple, tout en
l'affichage de contenu HTML statique). Par défaut, l'exécution JavaScript est désactivée dans WebView.
Supprimer l'interface JavaScript lors du chargement de contenu non approuvé
Assurez-vous que les objets de l'interface JavaScript sont supprimés en appelant removeJavascriptInterface
avant que le contenu non approuvé ne soit chargé dans WebView. Par exemple, vous pouvez le faire dans un appel à shouldInterceptRequest
.
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Charger uniquement du contenu Web via HTTPS
Si vous devez charger du contenu non approuvé, assurez-vous que la WebView charge le contenu Web via une connexion chiffrée (voir également nos consignes sur les communications en texte clair). Empêchez le chargement initial de la page sur des connexions non chiffrées en définissant android:usesCleartextTraffic
sur false
dans le fichier AndroidManifest
ou en interdisant le trafic HTTP dans une configuration de sécurité réseau. Pour en savoir plus, consultez la documentation sur usesCleartextTraffic
.
XML
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Pour s'assurer que les redirections et la navigation dans l'application n'ont pas lieu sur des applications non chiffrées
pour le trafic, recherchez le schéma HTTP dans loadUrl
ou
shouldInterceptRequest
:
Kotlin
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
Java
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
Valider le contenu non approuvé
Si des liens externes sont chargés dans une WebView, validez le schéma et l'hôte. (domaines de la liste d'autorisation). Les domaines qui ne figurent pas sur la liste d'autorisation doivent être ouverts par le navigateur par défaut.
Ne pas charger de contenu non fiable
Si possible, ne chargez que des URL strictement limitées et du contenu appartenant à l'application. développeur dans WebView.
Ne pas exposer les données sensibles
Si votre application accède à des données sensibles avec une WebView, envisagez d'utiliser la méthode clearCache
pour supprimer tous les fichiers stockés localement, avant d'utiliser l'interface JavaScript. Vous pouvez également utiliser des en-têtes côté serveur, tels que "no-store", pour
indiquent qu'une application ne doit pas mettre en cache un contenu particulier.
N'exposez pas les fonctionnalités sensibles
Si votre application nécessite des autorisations sensibles ou collecte des données sensibles, vous assurer qu'il est appelé à partir du code de l'application et que ne sont pas divulguées aux utilisateurs. Évitez d'utiliser des interfaces JavaScript pour toute opération ou donnée utilisateur sensible.
Niveau d'API cible 21 ou supérieur
Une méthode sécurisée d'utiliser la méthode addJavascriptInterface
consiste à cibler le niveau d'API 21 ou supérieur en vous assurant que la méthode n'est appelée que lorsqu'elle s'exécute au niveau d'API 21 ou supérieur. Avant l'API 21, JavaScript pouvait utiliser la réflexion pour accéder au public
d'un objet injecté.
Risque: risques liés à MessageChannel
L'absence de contrôle de l'origine dans postWebMessage()
et postMessage()
pourrait permettre aux pirates informatiques d'intercepter des messages ou d'en envoyer à des gestionnaires natifs.
Stratégies d'atténuation
Lorsque vous configurez postWebMessage()
ou postMessage()
, n'autorisez que les messages provenant
domaines de confiance en évitant d'utiliser * comme origine cible, et
le domaine d'envoi attendu.
Ressources
- Bonnes pratiques postMessage()
- Documentation sur addJavascriptInterface
- Documentation postMessage()
- Documentation de WebMessagePort.postMessage()
- Documentation sur WebViewClient.shouldInterceptRequest
- Documentation des conseils de sécurité concernant addJavascriptInterface
- Documentation clearCache
- documentation sur la suppression de JavaScript
- activer JavaScript dans les WebViews ;