hacktricks/src/mobile-pentesting/android-app-pentesting/android-applications-basics.md

368 lines
30 KiB
Markdown

# Bases des applications Android
{{#include ../../banners/hacktricks-training.md}}
## Modèle de sécurité Android
**Il y a deux couches :**
- Le **système d'exploitation**, qui maintient les applications installées isolées les unes des autres.
- L'**application elle-même**, qui permet aux développeurs de **dévoiler certaines fonctionnalités** et configure les capacités de l'application.
### Séparation des UID
**Chaque application se voit attribuer un identifiant utilisateur spécifique**. Cela se fait lors de l'installation de l'application afin que **l'application ne puisse interagir qu'avec les fichiers appartenant à son identifiant utilisateur ou les fichiers partagés**. Par conséquent, seule l'application elle-même, certains composants du système d'exploitation et l'utilisateur root peuvent accéder aux données des applications.
### Partage des UID
**Deux applications peuvent être configurées pour utiliser le même UID**. Cela peut être utile pour partager des informations, mais si l'une d'elles est compromise, les données des deux applications seront compromises. C'est pourquoi ce comportement est **déconseillé**.\
**Pour partager le même UID, les applications doivent définir la même valeur `android:sharedUserId` dans leurs manifestes.**
### Sandboxing
Le **sandboxing des applications Android** permet d'exécuter **chaque application** comme un **processus séparé sous un identifiant utilisateur distinct**. Chaque processus a sa propre machine virtuelle, donc le code d'une application s'exécute en isolation par rapport aux autres applications.\
Depuis Android 5.0(L), **SELinux** est appliqué. En gros, SELinux a refusé toutes les interactions entre processus et a ensuite créé des politiques pour **permettre uniquement les interactions attendues entre eux**.
### Permissions
Lorsque vous installez une **application et qu'elle demande des permissions**, l'application demande les permissions configurées dans les éléments **`uses-permission`** du fichier **AndroidManifest.xml**. L'élément **uses-permission** indique le nom de la permission demandée dans l'**attribut name**. Il a également l'attribut **maxSdkVersion** qui arrête de demander des permissions sur les versions supérieures à celle spécifiée.\
Notez que les applications Android n'ont pas besoin de demander toutes les permissions au début, elles peuvent également **demander des permissions dynamiquement**, mais toutes les permissions doivent être **déclarées** dans le **manifest**.
Lorsqu'une application expose une fonctionnalité, elle peut limiter **l'accès uniquement aux applications ayant une permission spécifiée**.\
Un élément de permission a trois attributs :
- Le **nom** de la permission
- L'attribut **permission-group**, qui permet de regrouper des permissions liées.
- Le **niveau de protection** qui indique comment les permissions sont accordées. Il existe quatre types :
- **Normal** : Utilisé lorsqu'il n'y a **aucune menace connue** pour l'application. L'utilisateur **n'est pas tenu de l'approuver**.
- **Dangerous** : Indique que la permission accorde à l'application demandeuse un **accès élevé**. **Les utilisateurs sont invités à les approuver**.
- **Signature** : Seules les **applications signées par le même certificat que celui** exportant le composant peuvent se voir accorder la permission. C'est le type de protection le plus fort.
- **SignatureOrSystem** : Seules les **applications signées par le même certificat que celui** exportant le composant ou **les applications fonctionnant avec un accès au niveau système** peuvent se voir accorder des permissions.
## Applications préinstallées
Ces applications se trouvent généralement dans les répertoires **`/system/app`** ou **`/system/priv-app`** et certaines d'entre elles sont **optimisées** (vous ne trouverez peut-être même pas le fichier `classes.dex`). Ces applications valent la peine d'être vérifiées car parfois elles **fonctionnent avec trop de permissions** (en tant que root).
- Celles fournies avec le **ROM** (Android OpenSource Project) **AOSP**
- Ajoutées par le **fabricant** de l'appareil
- Ajoutées par le **fournisseur de téléphonie mobile** (si achetées chez eux)
## Rooting
Pour obtenir un accès root sur un appareil Android physique, vous devez généralement **exploiter** 1 ou 2 **vulnérabilités** qui sont souvent **spécifiques** à l'**appareil** et à la **version**.\
Une fois l'exploitation réussie, le binaire Linux `su` est généralement copié dans un emplacement spécifié dans la variable d'environnement PATH de l'utilisateur comme `/system/xbin`.
Une fois le binaire su configuré, une autre application Android est utilisée pour interagir avec le binaire `su` et **traiter les demandes d'accès root** comme **Superuser** et **SuperSU** (disponible sur le Google Play Store).
> [!CAUTION]
> Notez que le processus de rooting est très dangereux et peut endommager gravement l'appareil.
### ROMs
Il est possible de **remplacer le système d'exploitation en installant un firmware personnalisé**. Ce faisant, il est possible d'étendre l'utilité d'un ancien appareil, de contourner les restrictions logicielles ou d'accéder au dernier code Android.\
**OmniROM** et **LineageOS** sont deux des firmwares les plus populaires à utiliser.
Notez que **ce n'est pas toujours nécessaire de rooter l'appareil** pour installer un firmware personnalisé. **Certains fabricants permettent** le déverrouillage de leurs bootloaders de manière bien documentée et sécurisée.
### Implications
Une fois un appareil rooté, n'importe quelle application pourrait demander un accès en tant que root. Si une application malveillante obtient cet accès, elle pourra accéder à presque tout et pourra endommager le téléphone.
## Fondamentaux des applications Android <a href="#2-android-application-fundamentals" id="2-android-application-fundamentals"></a>
- Le format des applications Android est appelé _format de fichier APK_. C'est essentiellement un **fichier ZIP** (en renommant l'extension de fichier en .zip, le contenu peut être extrait et visualisé).
- Contenu de l'APK (non exhaustif)
- **AndroidManifest.xml**
- resources.arsc/strings.xml
- resources.arsc : contient des ressources précompilées, comme du XML binaire.
- res/xml/files_paths.xml
- META-INF/
- C'est ici que se trouve le certificat !
- **classes.dex**
- Contient du bytecode Dalvik, représentant le code Java (ou Kotlin) compilé que l'application exécute par défaut.
- lib/
- Contient des bibliothèques natives, séparées par architecture CPU dans des sous-répertoires.
- `armeabi` : code pour processeurs basés sur ARM
- `armeabi-v7a` : code pour processeurs ARMv7 et supérieurs
- `x86` : code pour processeurs X86
- `mips` : code uniquement pour processeurs MIPS
- assets/
- Stocke des fichiers divers nécessaires à l'application, pouvant inclure des bibliothèques natives supplémentaires ou des fichiers DEX, parfois utilisés par des auteurs de logiciels malveillants pour dissimuler du code supplémentaire.
- res/
- Contient des ressources qui ne sont pas compilées dans resources.arsc
### **Dalvik & Smali**
Dans le développement Android, **Java ou Kotlin** est utilisé pour créer des applications. Au lieu d'utiliser la JVM comme dans les applications de bureau, Android compile ce code en **bytecode exécutable Dalvik (DEX)**. Auparavant, la machine virtuelle Dalvik gérait ce bytecode, mais maintenant, l'Android Runtime (ART) prend le relais dans les versions Android plus récentes.
Pour l'ingénierie inverse, **Smali** devient crucial. C'est la version lisible par l'homme du bytecode DEX, agissant comme un langage d'assemblage en traduisant le code source en instructions de bytecode. Smali et baksmali font référence aux outils d'assemblage et de désassemblage dans ce contexte.
## Intents
Les intents sont le principal moyen par lequel les applications Android communiquent entre leurs composants ou avec d'autres applications. Ces objets de message peuvent également transporter des données entre des applications ou des composants, similaire à la façon dont les requêtes GET/POST sont utilisées dans les communications HTTP.
Ainsi, un Intent est essentiellement un **message qui est passé entre des composants**. Les Intents **peuvent être dirigés** vers des composants ou des applications spécifiques, **ou peuvent être envoyés sans destinataire spécifique**.\
Pour simplifier, un Intent peut être utilisé :
- Pour démarrer une activité, généralement en ouvrant une interface utilisateur pour une application
- Comme des diffusions pour informer le système et les applications des changements
- Pour démarrer, arrêter et communiquer avec un service en arrière-plan
- Pour accéder aux données via des ContentProviders
- Comme des rappels pour gérer des événements
S'ils sont vulnérables, **les Intents peuvent être utilisés pour effectuer une variété d'attaques**.
### Filtre d'Intent
**Les filtres d'intent** définissent **comment une activité, un service ou un récepteur de diffusion peut interagir avec différents types d'intents**. Essentiellement, ils décrivent les capacités de ces composants, telles que les actions qu'ils peuvent effectuer ou les types de diffusions qu'ils peuvent traiter. L'endroit principal pour déclarer ces filtres est dans le **fichier AndroidManifest.xml**, bien que pour les récepteurs de diffusion, les coder soit également une option.
Les filtres d'intent sont composés de catégories, d'actions et de filtres de données, avec la possibilité d'inclure des métadonnées supplémentaires. Cette configuration permet aux composants de gérer des Intents spécifiques qui correspondent aux critères déclarés.
Un aspect critique des composants Android (activités/services/content providers/récepteurs de diffusion) est leur visibilité ou **statut public**. Un composant est considéré comme public et peut interagir avec d'autres applications s'il est **`exported`** avec une valeur de **`true`** ou si un filtre d'intent est déclaré pour lui dans le manifeste. Cependant, il existe un moyen pour les développeurs de garder ces composants privés, garantissant qu'ils n'interagissent pas avec d'autres applications de manière non intentionnelle. Cela se fait en définissant l'attribut **`exported`** sur **`false`** dans leurs définitions de manifeste.
De plus, les développeurs ont la possibilité de sécuriser davantage l'accès à ces composants en exigeant des permissions spécifiques. L'attribut **`permission`** peut être défini pour imposer que seules les applications ayant la permission désignée puissent accéder au composant, ajoutant une couche supplémentaire de sécurité et de contrôle sur qui peut interagir avec lui.
```java
<activity android:name=".MyActivity" android:exported="false">
<!-- Intent filters go here -->
</activity>
```
### Intents implicites
Les intents sont créés de manière programmatique à l'aide d'un constructeur Intent :
```java
Intent email = new Intent(Intent.ACTION_SEND, Uri.parse("mailto:"));
```
L'**Action** de l'intention précédemment déclarée est **ACTION_SEND** et l'**Extra** est un mailto **Uri** (l'Extra est l'information supplémentaire que l'intention attend).
Cette intention doit être déclarée dans le manifeste comme dans l'exemple suivant :
```xml
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
```
Un intent-filter doit correspondre à l'**action**, aux **données** et à la **catégorie** pour recevoir un message.
Le processus de "résolution d'intent" détermine quelle application doit recevoir chaque message. Ce processus prend en compte l'**attribut de priorité**, qui peut être défini dans la **déclaration d'intent-filter**, et **celui avec la priorité la plus élevée sera sélectionné**. Cette priorité peut être définie entre -1000 et 1000 et les applications peuvent utiliser la valeur `SYSTEM_HIGH_PRIORITY`. Si un **conflit** survient, une fenêtre "choisir" apparaît pour que l'**utilisateur puisse décider**.
### Intents explicites
Un intent explicite spécifie le nom de la classe qu'il cible :
```java
Intent downloadIntent = new (this, DownloadService.class):
```
Dans d'autres applications, pour accéder à l'intention précédemment déclarée, vous pouvez utiliser :
```java
Intent intent = new Intent();
intent.setClassName("com.other.app", "com.other.app.ServiceName");
context.startService(intent);
```
### Pending Intents
Ces derniers permettent à d'autres applications de **prendre des actions au nom de votre application**, en utilisant l'identité et les autorisations de votre application. Pour construire un Pending Intent, il faut **spécifier un intent et l'action à effectuer**. Si l'**intent déclaré n'est pas explicite** (ne déclare pas quel intent peut l'appeler), une **application malveillante pourrait effectuer l'action déclarée** au nom de l'application victime. De plus, **si une action n'est pas spécifiée**, l'application malveillante pourra effectuer **n'importe quelle action au nom de la victime**.
### Broadcast Intents
Contrairement aux intents précédents, qui ne sont reçus que par une seule application, les intents de diffusion **peuvent être reçus par plusieurs applications**. Cependant, à partir de la version API 14, il est **possible de spécifier l'application qui doit recevoir** le message en utilisant Intent.setPackage.
Il est également possible de **spécifier une autorisation lors de l'envoi de la diffusion**. L'application réceptrice devra avoir cette autorisation.
Il existe **deux types** de diffusions : **Normale** (asynchrone) et **Ordonnée** (synchronisée). L'**ordre** est basé sur la **priorité configurée dans l'élément récepteur**. **Chaque application peut traiter, relayer ou ignorer la diffusion.**
Il est possible de **envoyer** une **diffusion** en utilisant la fonction `sendBroadcast(intent, receiverPermission)` de la classe `Context`.\ Vous pouvez également utiliser la fonction **`sendBroadcast`** de **`LocalBroadCastManager`** qui garantit que le **message ne quitte jamais l'application**. Avec cela, vous n'aurez même pas besoin d'exporter un composant récepteur.
### Sticky Broadcasts
Ce type de diffusions **peut être accessible longtemps après leur envoi**.\
Celles-ci ont été dépréciées au niveau API 21 et il est recommandé de **ne pas les utiliser**.\
**Elles permettent à n'importe quelle application d'intercepter les données, mais aussi de les modifier.**
Si vous trouvez des fonctions contenant le mot "sticky" comme **`sendStickyBroadcast`** ou **`sendStickyBroadcastAsUser`**, **vérifiez l'impact et essayez de les supprimer**.
## Deep links / URL schemes
Dans les applications Android, les **deep links** sont utilisés pour initier une action (Intent) directement via une URL. Cela se fait en déclarant un **schéma d'URL** spécifique dans une activité. Lorsque un appareil Android essaie d'**accéder à une URL avec ce schéma**, l'activité spécifiée dans l'application est lancée.
Le schéma doit être déclaré dans le fichier **`AndroidManifest.xml`** :
```xml
[...]
<activity android:name=".MyActivity">
<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="examplescheme" />
</intent-filter>
[...]
```
Le schéma de l'exemple précédent est `examplescheme://` (notez également la **`catégorie BROWSABLE`**)
Ensuite, dans le champ de données, vous pouvez spécifier le **hôte** et le **chemin** :
```xml
<data android:scheme="examplescheme"
android:host="example"
/>
```
Pour y accéder depuis le web, il est possible de définir un lien comme :
```xml
<a href="examplescheme://example/something">click here</a>
<a href="examplescheme://example/javascript://%250dalert(1)">click here</a>
```
Pour trouver le **code qui sera exécuté dans l'application**, allez à l'activité appelée par le deeplink et recherchez la fonction **`onNewIntent`**.
Apprenez à [appeler des deep links sans utiliser de pages HTML](#exploiting-schemes-deep-links).
## AIDL - Android Interface Definition Language
Le **Android Interface Definition Language (AIDL)** est conçu pour faciliter la communication entre le client et le service dans les applications Android via **la communication interprocessus** (IPC). Étant donné qu'il n'est pas permis d'accéder directement à la mémoire d'un autre processus sur Android, AIDL simplifie le processus en marshalling des objets dans un format compris par le système d'exploitation, facilitant ainsi la communication entre différents processus.
### Concepts Clés
- **Services Liés** : Ces services utilisent AIDL pour l'IPC, permettant aux activités ou composants de se lier à un service, de faire des demandes et de recevoir des réponses. La méthode `onBind` dans la classe du service est essentielle pour initier l'interaction, marquant ainsi un domaine vital pour l'examen de la sécurité à la recherche de vulnérabilités.
- **Messenger** : Fonctionnant comme un service lié, Messenger facilite l'IPC en se concentrant sur le traitement des données via la méthode `onBind`. Il est essentiel d'examiner cette méthode de près pour toute manipulation de données non sécurisée ou exécution de fonctions sensibles.
- **Binder** : Bien que l'utilisation directe de la classe Binder soit moins courante en raison de l'abstraction d'AIDL, il est bénéfique de comprendre que Binder agit comme un pilote au niveau du noyau facilitant le transfert de données entre les espaces mémoire de différents processus. Pour une compréhension plus approfondie, une ressource est disponible à [https://www.youtube.com/watch?v=O-UHvFjxwZ8](https://www.youtube.com/watch?v=O-UHvFjxwZ8).
## Composants
Cela inclut : **Activités, Services, Récepteurs de Diffusion et Fournisseurs.**
### Activité de Lancement et autres activités
Dans les applications Android, les **activités** sont comme des écrans, montrant différentes parties de l'interface utilisateur de l'application. Une application peut avoir de nombreuses activités, chacune présentant un écran unique à l'utilisateur.
L'**activité de lancement** est la principale porte d'entrée d'une application, lancée lorsque vous appuyez sur l'icône de l'application. Elle est définie dans le fichier manifeste de l'application avec des intents spécifiques MAIN et LAUNCHER :
```html
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
```
Toutes les applications n'ont pas besoin d'une activité de lancement, en particulier celles sans interface utilisateur, comme les services en arrière-plan.
Les activités peuvent être rendues disponibles à d'autres applications ou processus en les marquant comme "exportées" dans le manifeste. Ce paramètre permet à d'autres applications de démarrer cette activité :
```markdown
<service android:name=".ExampleExportedService" android:exported="true"/>
```
Cependant, accéder à une activité d'une autre application n'est pas toujours un risque de sécurité. Le problème se pose si des données sensibles sont partagées de manière inappropriée, ce qui pourrait entraîner des fuites d'informations.
Le cycle de vie d'une activité **commence avec la méthode onCreate**, configurant l'interface utilisateur et préparant l'activité pour l'interaction avec l'utilisateur.
### Sous-classe d'application
Dans le développement Android, une application a la possibilité de créer une **sous-classe** de la classe [Application](https://developer.android.com/reference/android/app/Application), bien que ce ne soit pas obligatoire. Lorsqu'une telle sous-classe est définie, elle devient la première classe à être instanciée dans l'application. La méthode **`attachBaseContext`**, si elle est implémentée dans cette sous-classe, est exécutée avant la méthode **`onCreate`**. Cette configuration permet une initialisation précoce avant que le reste de l'application ne démarre.
```java
public class MyApp extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// Initialization code here
}
@Override
public void onCreate() {
super.onCreate();
// More initialization code
}
}
```
### Services
[Services](https://developer.android.com/guide/components/services) sont des **opérateurs en arrière-plan** capables d'exécuter des tâches sans interface utilisateur. Ces tâches peuvent continuer à s'exécuter même lorsque les utilisateurs passent à d'autres applications, rendant les services cruciaux pour des **opérations de longue durée**.
Les services sont polyvalents ; ils peuvent être initiés de différentes manières, les **Intents** étant la méthode principale pour les lancer en tant que point d'entrée d'une application. Une fois qu'un service est démarré en utilisant la méthode `startService`, sa méthode `onStart` entre en action et continue de s'exécuter jusqu'à ce que la méthode `stopService` soit explicitement appelée. Alternativement, si le rôle d'un service dépend d'une connexion client active, la méthode `bindService` est utilisée pour lier le client au service, engageant la méthode `onBind` pour le passage de données.
Une application intéressante des services inclut la lecture de musique en arrière-plan ou la récupération de données réseau sans entraver l'interaction de l'utilisateur avec une application. De plus, les services peuvent être rendus accessibles à d'autres processus sur le même appareil par le biais de **l'exportation**. Ce n'est pas le comportement par défaut et nécessite une configuration explicite dans le fichier Android Manifest :
```xml
<service android:name=".ExampleExportedService" android:exported="true"/>
```
### Broadcast Receivers
**Les récepteurs de diffusion** agissent comme des écouteurs dans un système de messagerie, permettant à plusieurs applications de répondre aux mêmes messages du système. Une application peut **enregistrer un récepteur** de **deux manières principales** : via le **Manifest** de l'application ou **dynamiquement** dans le code de l'application via l'API **`registerReceiver`**. Dans le Manifest, les diffusions sont filtrées avec des permissions, tandis que les récepteurs enregistrés dynamiquement peuvent également spécifier des permissions lors de l'enregistrement.
Les **filtres d'intention** sont cruciaux dans les deux méthodes d'enregistrement, déterminant quelles diffusions déclenchent le récepteur. Une fois qu'une diffusion correspondante est envoyée, la méthode **`onReceive`** du récepteur est invoquée, permettant à l'application de réagir en conséquence, comme ajuster le comportement en réponse à une alerte de batterie faible.
Les diffusions peuvent être **asynchrones**, atteignant tous les récepteurs sans ordre, ou **synchrones**, où les récepteurs reçoivent la diffusion en fonction des priorités définies. Cependant, il est important de noter le risque de sécurité potentiel, car toute application peut se prioriser pour intercepter une diffusion.
Pour comprendre la fonctionnalité d'un récepteur, recherchez la méthode **`onReceive`** dans sa classe. Le code de cette méthode peut manipuler l'Intent reçu, soulignant la nécessité de validation des données par les récepteurs, en particulier dans les **Diffusions Ordonnées**, qui peuvent modifier ou supprimer l'Intent.
### Content Provider
**Les Fournisseurs de Contenu** sont essentiels pour **partager des données structurées** entre les applications, soulignant l'importance de la mise en œuvre de **permissions** pour garantir la sécurité des données. Ils permettent aux applications d'accéder à des données provenant de diverses sources, y compris des bases de données, des systèmes de fichiers ou le web. Des permissions spécifiques, comme **`readPermission`** et **`writePermission`**, sont cruciales pour contrôler l'accès. De plus, un accès temporaire peut être accordé via les paramètres **`grantUriPermission`** dans le manifest de l'application, en utilisant des attributs tels que `path`, `pathPrefix` et `pathPattern` pour un contrôle d'accès détaillé.
La validation des entrées est primordiale pour prévenir les vulnérabilités, telles que l'injection SQL. Les Fournisseurs de Contenu prennent en charge les opérations de base : `insert()`, `update()`, `delete()`, et `query()`, facilitant la manipulation et le partage de données entre les applications.
**FileProvider**, un Fournisseur de Contenu spécialisé, se concentre sur le partage sécurisé de fichiers. Il est défini dans le manifest de l'application avec des attributs spécifiques pour contrôler l'accès aux dossiers, désignés par `android:exported` et `android:resource` pointant vers les configurations de dossier. Une prudence est conseillée lors du partage de répertoires pour éviter d'exposer involontairement des données sensibles.
Exemple de déclaration de manifest pour FileProvider :
```xml
<provider android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
```
Et un exemple de spécification des dossiers partagés dans `filepaths.xml` :
```xml
<paths>
<files-path path="images/" name="myimages" />
</paths>
```
Pour plus d'informations, consultez :
- [Android Developers: Content Providers](https://developer.android.com/guide/topics/providers/content-providers)
- [Android Developers: FileProvider](https://developer.android.com/training/secure-file-sharing/setup-sharing)
## WebViews
Les WebViews sont comme des **mini navigateurs web** à l'intérieur des applications Android, tirant du contenu soit du web, soit de fichiers locaux. Ils font face à des risques similaires à ceux des navigateurs classiques, mais il existe des moyens de **réduire ces risques** grâce à des **paramètres** spécifiques.
Android propose deux types principaux de WebView :
- **WebViewClient** est excellent pour le HTML de base mais ne prend pas en charge la fonction d'alerte JavaScript, ce qui affecte la manière dont les attaques XSS peuvent être testées.
- **WebChromeClient** agit davantage comme l'expérience complète du navigateur Chrome.
Un point clé est que les navigateurs WebView ne **partagent pas les cookies** avec le navigateur principal de l'appareil.
Pour charger du contenu, des méthodes telles que `loadUrl`, `loadData` et `loadDataWithBaseURL` sont disponibles. Il est crucial de s'assurer que ces URL ou fichiers sont **sûrs à utiliser**. Les paramètres de sécurité peuvent être gérés via la classe `WebSettings`. Par exemple, désactiver JavaScript avec `setJavaScriptEnabled(false)` peut prévenir les attaques XSS.
Le "Bridge" JavaScript permet aux objets Java d'interagir avec JavaScript, nécessitant que les méthodes soient marquées avec `@JavascriptInterface` pour des raisons de sécurité à partir d'Android 4.2.
Autoriser l'accès au contenu (`setAllowContentAccess(true)`) permet aux WebViews d'accéder aux Content Providers, ce qui pourrait être un risque à moins que les URL de contenu ne soient vérifiées comme sécurisées.
Pour contrôler l'accès aux fichiers :
- Désactiver l'accès aux fichiers (`setAllowFileAccess(false)`) limite l'accès au système de fichiers, avec des exceptions pour certains actifs, garantissant qu'ils ne sont utilisés que pour du contenu non sensible.
## Autres composants d'application et gestion des appareils mobiles
### **Signature numérique des applications**
- La **signature numérique** est indispensable pour les applications Android, garantissant qu'elles sont **authentiquement créées** avant l'installation. Ce processus utilise un certificat pour l'identification de l'application et doit être vérifié par le gestionnaire de paquets de l'appareil lors de l'installation. Les applications peuvent être **auto-signées ou certifiées par une CA externe**, protégeant contre l'accès non autorisé et garantissant que l'application reste intacte lors de sa livraison à l'appareil.
### **Vérification des applications pour une sécurité renforcée**
- À partir d'**Android 4.2**, une fonctionnalité appelée **Vérifier les applications** permet aux utilisateurs de faire vérifier les applications pour leur sécurité avant l'installation. Ce **processus de vérification** peut avertir les utilisateurs contre des applications potentiellement nuisibles, ou même empêcher l'installation de celles particulièrement malveillantes, renforçant ainsi la sécurité des utilisateurs.
### **Gestion des appareils mobiles (MDM)**
- Les **solutions MDM** fournissent une **supervision et une sécurité** pour les appareils mobiles via l'**API d'administration des appareils**. Elles nécessitent l'installation d'une application Android pour gérer et sécuriser efficacement les appareils mobiles. Les fonctions clés incluent **l'application de politiques de mot de passe**, **l'obligation de chiffrement des données**, et **la possibilité d'effacer des données à distance**, garantissant un contrôle et une sécurité complets sur les appareils mobiles.
```java
// Example of enforcing a password policy with MDM
DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminComponent = new ComponentName(context, AdminReceiver.class);
if (dpm.isAdminActive(adminComponent)) {
// Set minimum password length
dpm.setPasswordMinimumLength(adminComponent, 8);
}
```
{{#include ../../banners/hacktricks-training.md}}