Catégorie OWASP : MASVS-CODE : qualité du code
Présentation
Les risques associés aux autorisations personnalisées surviennent lorsque la définition des autorisations personnalisées est manquante ou mal orthographiée, ou lorsque l'attribut android:protectionLevel correspondant est mal utilisé dans le fichier manifeste.
Par exemple, ces risques peuvent être exploités en créant une autorisation personnalisée portant le même nom, mais définie par une application malveillante et avec des niveaux de protection différents.
Les autorisations personnalisées sont conçues pour permettre le partage de ressources et de fonctionnalités avec d'autres applications. Voici quelques exemples d'utilisation légitime des autorisations personnalisées :
- Contrôle de la communication interprocessus (IPC) entre au moins deux applications
- Accès à des services tiers
- Restriction de l'accès aux données partagées d'une application
Impact
Si cette faille est exploitée, une application malveillante peut accéder à des ressources initialement destinées à être protégées. Les implications de la faille dépendent de la ressource protégée et des autorisations associées au service d'application d'origine.
Risque : fautes de frappe dans les autorisations personnalisées
Une autorisation personnalisée peut être déclarée dans le fichier manifeste, mais une autre autorisation personnalisée est utilisée pour protéger les composants Android exportés en raison d'une faute de frappe. Une application malveillante peut tirer parti des applications qui ont mal orthographié une autorisation en procédant de l'une des manières suivantes :
- Enregistrement de cette autorisation en premier
- Anticipation de l'orthographe dans les applications suivantes
Cela peut permettre à une application d'accéder sans autorisation à des ressources ou de contrôler l'application victime.
Par exemple, une application vulnérable souhaite protéger un composant à l'aide d'une autorisation READ_CONTACTS, mais elle l'orthographie accidentellement READ_CONACTS. Une application malveillante peut revendiquer READ_CONACTS, car elle n'appartient à aucune application (ni au système) et accéder au composant protégé. android:permission=True est une autre variante courante de cette faille. Les valeurs telles que true et false, quelle que soit la casse, ne sont pas des entrées valides pour la déclaration d'autorisation et sont traitées de la même manière que les autres fautes de frappe dans la déclaration d'autorisation personnalisée. Pour résoudre ce problème, la valeur de l'attribut android:permission doit être remplacée par une chaîne d'autorisation valide. Par exemple, si l'application doit accéder aux contacts de l'utilisateur, la valeur de l'attribut android:permission doit être android.permission.READ_CONTACTS.
Stratégies d'atténuation
Vérifications Android Lint
Lorsque vous déclarez des autorisations personnalisées, utilisez les vérifications Android Lint pour vous aider à trouver les fautes de frappe et autres erreurs potentielles dans votre code.
Convention d'attribution de noms
Utilisez une convention d'attribution de noms cohérente pour rendre les fautes de frappe plus visibles. Vérifiez attentivement les déclarations d'autorisation personnalisées dans le fichier manifeste de votre application pour détecter les fautes de frappe.
Risque : autorisations orphelines
Les autorisations permettent de protéger les ressources des applications. Une application peut déclarer les autorisations requises pour accéder aux ressources à deux endroits différents :
- AndroidManifest.xml : prédéfini dans le fichier AndroidManifest.xml (si aucune autorisation n'est
spécifiée, les autorisations
<application>sont utilisées), par exemple, autorisation de fournisseur, autorisation de récepteur, autorisation d'activité, autorisation de service ; - Code : enregistré dans le code d'exécution, par exemple,
registerReceiver().
Toutefois, ces autorisations ne sont parfois pas définies par une balise correspondante
<permission> dans le fichier manifeste d'un APK sur l'appareil. Dans ce cas, elles sont appelées autorisations orphelines. Cette situation peut se produire pour plusieurs raisons, par exemple :
- Il peut y avoir une désynchronisation entre les mises à jour du fichier manifeste et le code avec la vérification des autorisations.
- L'APK avec les autorisations n'est peut-être pas inclus dans la compilation, ou la mauvaise version peut être incluse.
- Le nom de l'autorisation dans la vérification ou le fichier manifeste peut être mal orthographié.
Une application malveillante peut définir une autorisation orpheline et l'acquérir. Dans ce cas, les applications privilégiées qui font confiance à l'autorisation orpheline pour protéger un composant peuvent être compromises.
Si l'application privilégiée utilise l'autorisation pour protéger ou restreindre un composant, cela peut accorder à l'application malveillante l'accès à ce composant. Par exemple, le lancement d'activités protégées par une autorisation, l'accès à un fournisseur de contenu ou la diffusion à un récepteur de diffusion protégé par l'autorisation orpheline.
Cela peut également créer une situation dans laquelle l'application privilégiée est amenée à croire que l'application malveillante est une application légitime et, par conséquent, à charger des fichiers ou du contenu.
Stratégies d'atténuation
Assurez-vous que toutes les autorisations personnalisées que votre application utilise pour protéger les composants sont également définies dans votre fichier manifeste.
L'application utilise les autorisations personnalisées my.app.provider.READ et my.app.provider.WRITE afin de protéger l'accès à un fournisseur de contenu :
XML
<provider android:name="my.app.database.CommonContentProvider" android:readPermission="my.app.provider.READ" android:writePermission="my.app.provider.WRITE" android:exported="true" android:process=":myappservice" android:authorities="my.app.database.contentprovider"/>
L'application définit et utilise également ces autorisations personnalisées, ce qui empêche d'autres applications malveillantes de le faire :
XML
<permission android:name="my.app.provider.READ"/>
<permission android:name="my.app.provider.WRITE"/>
<uses-permission android:name="my.app.provider.READ" />
<uses-permission android:name="my.app.provider.WRITE" />
Risque : mauvaise utilisation de android:protectionLevel
Cet attribut décrit le niveau de risque potentiel de l'autorisation et indique les procédures que le système doit suivre pour décider d'accorder ou non l'autorisation.
Stratégies d'atténuation
Éviter le niveau de protection normal ou dangereux
Si vous utilisez un protectionLevel normal ou dangereux pour vos autorisations, la plupart des applications peuvent demander et obtenir l'autorisation :
- "normal" ne nécessite que sa déclaration.
- "dangereux" sera approuvé par de nombreux utilisateurs.
Par conséquent, ces protectionLevels offrent peu de sécurité.
Utiliser des autorisations de signature (Android >= 10)
Utilisez des niveaux de protection de signature dans la mesure du possible. L'utilisation de cette fonctionnalité garantit que seules les autres applications signées avec le même certificat que l'application qui a créé l'autorisation peuvent accéder à ces fonctionnalités protégées. Assurez-vous d'utiliser un certificat de signature dédié (non réutilisé) et stockez-le de manière sécurisée dans un keystore.
Définissez une autorisation personnalisée comme suit dans votre fichier manifeste :
XML
<permission
android:name="my.custom.permission.MY_PERMISSION"
android:protectionLevel="signature"/>
Restreignez l'accès, par exemple, à une activité, uniquement aux applications qui disposent de cette autorisation personnalisée, comme suit :
XML
<activity android:name=".MyActivity" android:permission="my.custom.permission.MY_PERMISSION"/>
Toute autre application signée avec le même certificat que l'application qui a déclaré cette autorisation personnalisée aura alors accès à l'activité .MyActivity et devra la déclarer comme suit dans son fichier manifeste :
XML
<uses-permission android:name="my.custom.permission.MY_PERMISSION" />
Attention aux autorisations personnalisées de signature (Android < 10)
Si votre application cible Android < 10, chaque fois que les autorisations personnalisées de votre application sont supprimées en raison de désinstallations ou de mises à jour, des applications malveillantes peuvent toujours utiliser ces autorisations personnalisées et contourner ainsi les vérifications. Cela est dû à une
faille d'élévation des privilèges (CVE-2019-2200) qui a été
corrigée dans Android 10.
C'est l'une des raisons (avec le risque de conditions de concurrence) pour lesquelles les vérifications de signature sont recommandées plutôt que les autorisations personnalisées.
Risque : condition de concurrence
Si une application légitime A définit une autorisation personnalisée de signature utilisée par d'autres applications X, mais qu'elle est ensuite désinstallée, une application malveillante B peut définir la même autorisation personnalisée avec un protectionLevel différent, par exemple normal. De cette façon, B accède à tous les composants protégés par cette autorisation personnalisée dans les applications X sans avoir besoin d'être signé avec le même certificat que l'application A.
Il en va de même si B est installé avant A.
Stratégies d'atténuation
Si vous souhaitez rendre un composant disponible uniquement pour les applications signées avec la même signature que l'application qui le fournit, vous pourrez peut-être éviter de définir des autorisations personnalisées pour restreindre l'accès à ce composant. Dans ce cas, vous pouvez utiliser des vérifications de signature. Lorsque l'une de vos applications envoie une requête à l'une de vos autres applications, celle-ci peut vérifier que les deux applications sont signées avec le même certificat avant de se conformer à la requête.
Ressources
- Réduire le nombre de demandes d'autorisation
- Présentation des autorisations
- Description des niveaux de protection
- Android Lint CustomPermissionTypo
- Utiliser un Android Lint
- Document de recherche contenant une explication détaillée des autorisations Android et des résultats de tests fuzzing intéressants