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é 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
  • Dangereux : autorisations à haut risque qui pourraient permettre d'accéder à des données utilisateur sensibles et qui nécessitent l'approbation explicite de l'utilisateur au moment de l'exécution
  • Signature : accordée uniquement aux applications signées avec le même certificat que l' application déclarant l'autorisation, généralement utilisée pour les applications système ou les interactions entre les applications du 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'application (tel qu'une activité, un récepteur, un fournisseur de contenu ou un service) répond à tous les critères suivants :

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

Dans ce cas, une application malveillante peut effectuer des actions sensibles en abusant des privilèges du composant vulnérable, en transférant les privilèges 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 effectuer des actions sensibles. L'impact de ce comportement indésirable dépend du contexte du composant vulnérable et de ses privilèges.

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 dispose de 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 et au-delà, 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 les signatures. 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 plus simple et plus 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 séparation des tâches. Chaque point de terminaison ne doit effectuer qu'un petit ensemble de tâches spécifiques avec des privilèges spécifiques. Cette bonne pratique de conception permet également au développeur d'appliquer des autorisations granulaires pour chaque point de terminaison. Par exemple, évitez de créer un point de terminaison unique qui sert à la fois d'agenda et de contacts.

Ressources