Contrôle des accès basé sur les autorisations pour les composants exportés

Catégorie OWASP : MASVS-PLATFORM : interaction avec la plate-forme

Présentation

Une autorisation Android est un identifiant de chaîne déclaré dans le fichier manifeste de l'application pour demander l'accès à des données ou des actions restreintes, appliquées au moment de l'exécution par le framework Android.

Les niveaux d'autorisation Android indiquent le risque potentiel associé à l'autorisation:

  • Normal: autorisations à faible risque, accordées automatiquement au moment de l'installation
  • Dangereuses: autorisations à haut risque pouvant permettre d'accéder à des données utilisateur sensibles, nécessitant l'approbation explicite de l'utilisateur au moment de l'exécution
  • Signature: n'est accordée qu'aux applications signées avec le même certificat que l'application déclarant l'autorisation. Elle est généralement utilisée pour les applications système ou les interactions entre les applications d'un même développeur.

Les failles liées aux contrôles d'accès basés sur les autorisations se produisent lorsqu'un composant d'une application (comme une activité, un récepteur, un fournisseur de contenu ou un service) remplit tous les critères suivants:

  • Le composant n'est associé à aucun android:permission dans Manifest.
  • Le composant effectue une tâche sensible pour laquelle une autorisation que l'utilisateur a déjà approuvée existe.
  • Le composant est exporté.
  • Le composant n'effectue aucune vérification manuelle (au niveau du fichier manifeste ou du code) des autorisations.

Lorsque cela se produit, une application malveillante peut effectuer des actions sensibles en abuseant des privilèges du composant vulnérable et en transmettant par proxy les droits de l'application vulnérable à l'application malveillante.

Impact

L'exportation de composants vulnérables peut être utilisée pour accéder à des ressources sensibles ou pour effectuer des actions sensibles. L'impact de ce comportement indésirable dépend du contexte du composant vulnérable et de ses droits.

Stratégies d'atténuation

Exiger des autorisations pour les tâches sensibles

Lorsque vous exportez un composant avec des autorisations sensibles, exigez ces mêmes autorisations pour toute requête entrante. L'IDE Android Studio effectue des vérifications lint pour les récepteurs et les services afin de détecter cette faille et de recommander d'exiger les autorisations appropriées.

Les développeurs peuvent exiger des autorisations pour les requêtes entrantes en les déclarant dans le fichier Manifest ou au niveau du code lors de l'implémentation du service, comme dans les exemples suivants.

XML

<manifest ...>
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application ...>
        <service android:name=".MyExportService"
                 android:exported="true"
                 android:permission="android.permission.READ_CONTACTS" />

        </application>
</manifest>

Kotlin

class MyExportService : Service() {

    private val binder = MyExportBinder()

    override fun onBind(intent: Intent): IBinder? {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
        // Permission is enforced, proceed with export logic
        return binder
    }

    // Inner class for your Binder implementation
    private inner class MyExportBinder : Binder() {
        // Permission is enforced, proceed with export logic
    }
}

Java

public class MyExportService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");

        return binder;

    }

    // Inner class for your Binder implementation
    private class MyExportBinder extends Binder {
        // Permission is enforced, proceed with export logic

    }
}

Ne pas exporter le composant

Évitez d'exporter des composants ayant accès à des ressources sensibles, sauf si cela est absolument nécessaire. Pour ce faire, définissez android:exported dans le fichier Manifest sur false pour votre composant. À partir du niveau d'API 31, cet attribut est défini sur false par défaut.

XML

<activity
    android:name=".MyActivity"
    android:exported="false"/>

Appliquer des autorisations basées sur les signatures

Lorsque vous partagez des données entre deux applications que vous contrôlez ou possédez, utilisez des autorisations basées sur la signature. Ces autorisations ne nécessitent pas de confirmation de l'utilisateur. Elles vérifient à la place que les applications accédant aux données sont signées à l'aide de la même clé de signature. Cette configuration offre une expérience utilisateur simplifiée et sécurisée. Si vous déclarez des autorisations personnalisées, tenez compte des consignes de sécurité correspondantes.

XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

Points de terminaison à tâche unique

Implémentez votre application en suivant le principe de conception de la séparation des préoccupations. Chaque point de terminaison ne doit effectuer qu'un petit ensemble de tâches spécifiques avec des droits spécifiques. Cette bonne pratique de conception permet également au développeur d'appliquer des autorisations précises pour chaque point de terminaison. Par exemple, évitez de créer un seul point de terminaison qui sert à la fois l'agenda et les contacts.

Ressources