Autorisation d'accéder au réseau local

Les appareils d'un réseau local (LAN) sont accessibles par n'importe quelle application disposant de l'autorisation INTERNET. Cela permet aux applications de se connecter facilement aux appareils locaux, mais cela a également des implications en termes de confidentialité, comme la création d'une empreinte de l'utilisateur et l'utilisation d'un proxy pour la position.

Le projet Local Network Protections vise à protéger la confidentialité de l'utilisateur en limitant l'accès au réseau local à une nouvelle autorisation d'exécution.

Impact

Dans Android 16, cette autorisation est une fonctionnalité d'activation, ce qui signifie que seules les applications qui l'activent seront concernées. L'objectif de l'activation est de permettre aux développeurs d'applications de comprendre quelles parties de leur application dépendent d'un accès implicite au réseau local afin qu'ils puissent se préparer à les protéger par autorisation dans une future version d'Android.

Les applications seront affectées si elles accèdent au réseau local de l'utilisateur à l'aide des éléments suivants :

  • Utilisation directe ou de bibliothèque de sockets bruts sur des adresses de réseau local, par exemple, Multicast DNS (mDNS) ou Simple Service Discovery Protocol (SSDP).
  • Utilisation de classes au niveau du framework qui accèdent au réseau local, par exemple, NsdManager.

Détails de l'impact

Le trafic vers et depuis une adresse de réseau local nécessite une autorisation d'accès au réseau local. Le tableau suivant répertorie quelques cas courants :

Opération réseau de bas niveau de l'application Autorisation de réseau local requise
Établir une connexion TCP sortante oui
Accepter une connexion TCP entrante oui
Envoyer une monodiffusion, une multidiffusion ou une diffusion UDP oui
Recevoir une monodiffusion, une multidiffusion ou une diffusion UDP entrante oui

Ces restrictions sont implémentées en profondeur dans la pile réseau et s'appliquent donc à toutes les API réseau. Cela inclut les sockets créés dans la plate-forme ou le code géré, les bibliothèques réseau telles que Cronet et OkHttp, ainsi que toutes les API implémentées au-dessus de celles-ci. Toute tentative de résolution de services sur le réseau local avec un suffixe .local nécessite une autorisation de réseau local.

Exceptions aux règles précédentes :

  • Si le serveur DNS d'un appareil se trouve sur un réseau local, le trafic vers / depuis celui-ci (sur le port 53) ne nécessite pas d'autorisation d'accès au réseau local.
  • Les applications qui utilisent Output Switcher comme sélecteur intégré n'auront pas besoin d'autorisations de réseau local (d'autres conseils seront fournis dans une version ultérieure).

Application d'Android 17

À partir d'Android 17, les protections du réseau local sont obligatoires et appliquées pour les applications ciblant Android 17 ou une version ultérieure.

Aspect Android 16 Android 17
SDK cible 36 37 ou version ultérieure
Autorisation NEARBY_WIFI_DEVICES utilisée temporairement ACCESS_LOCAL_NETWORK
Accès par défaut L'accès au réseau local est ouvert Le réseau local est bloqué par défaut pour toutes les applications qui mettent à jour leur SDK cible
Groupe d'autorisations Fait partie du groupe d'autorisations NEARBY_DEVICES existant

Pour vérifier que le fonctionnement de l'application n'est pas interrompu après l'application, les applications ciblant le SDK 37 ou une version ultérieure doivent adopter l'une des méthodes suivantes pour gérer l'accès au réseau local :

Méthode A : Utiliser des sélecteurs préservant la confidentialité

Pour les tâches de découverte et de connexion gérées par le système, utilisez des sélecteurs pour éviter de demander complètement l'autorisation d'exécution étendue. Utilisez les sélecteurs suivants en fonction de votre cas d'utilisation :

  • Streaming multimédia : pour les applications compatibles avec Google Cast, vous pouvez utiliser la fonctionnalité de sélecteur de sortie. Cela permet aux développeurs d'autoriser les utilisateurs à sélectionner des appareils de streaming spécifiques sans que l'application ait besoin de demander l'autorisation étendue ACCESS_LOCAL_NETWORK.
  • Connectivité générale : NsdManager inclut un sélecteur de service géré par le système pour la découverte mDNS. Au lieu que l'application analyse l'ensemble du réseau, le système affiche une boîte de dialogue permettant à l'utilisateur de sélectionner un seul appareil auquel l'application peut accéder.
val discoveryRequest = DiscoveryRequest.Builder("_http._tcp")
    .setFlags(DiscoveryRequest.FLAG_SHOW_PICKER)
    .build()

nsdManager.registerServiceInfoCallback(discoveryRequest, executor, object : NsdManager.ServiceInfoCallback {
    override fun onServiceUpdated(serviceInfo: NsdServiceInfo) {
        // Handle the user-selected and discovered service
        // NsdServiceInfo.getHostAddresses() can now be connected to
        // without ACCESS_LOCAL_NETWORK permission
    }
})

Méthode B : Demander une autorisation d'exécution (accès étendu)

Cette méthode est requise pour les cas d'utilisation complexes tels que l'automatisation de la maison ou la gestion des appareils IoT, qui nécessitent un accès étendu et persistant au réseau local.

  • Déclarez l'autorisation dans le fichier manifeste : déclarez explicitement ACCESS_LOCAL_NETWORK dans le AndroidManifest.xml.

  • Demandez l'autorisation lors de l'exécution : avant de tenter d'accéder au réseau local, les applications doivent vérifier si l'autorisation a été accordée. Si ce n'est pas le cas, elles doivent appeler Activity.requestPermission() pour déclencher l'invite système standard.

  • Scénario pré-accordé : l'autorisation ACCESS_LOCAL_NETWORK fait partie du groupe d'autorisations NEARBY_DEVICES. Si un utilisateur a déjà accordé une autre autorisation dans ce groupe (par exemple, les autorisations Bluetooth), il ne sera pas invité à accéder au réseau local.

  • Gérer le refus et la révocation : les applications doivent gérer correctement les cas où l'utilisateur refuse la demande ou révoque ultérieurement l'autorisation dans les paramètres système. Dans ce cas, le trafic réseau local sera bloqué.

Stratégie de compteur de réinitialisation des demandes d'autorisation

La plate-forme implémente une stratégie de réinitialisation du compteur qui gère les scénarios dans lesquels le refus antérieur par une application du groupe d'autorisations NEARBY_DEVICES(qui inclut désormais ACCESS_LOCAL_NETWORK) a empêché l'application de demander l'autorisation après avoir présenté de manière adéquate sa justification. Ce mécanisme offre à l'application des possibilités supplémentaires d'appeler l'API requestPermission(), ce qui réinitialise le nombre de refus pour l'autorisation ACCESS_LOCAL_NETWORK. Cela permet un réengagement plus nuancé avec l'utilisateur, en particulier lorsque le refus initial s'est produit avant que l'application ne puisse communiquer la nécessité d'un accès au réseau local pour sa fonctionnalité principale.

Modèle d'autorisation fractionné

L'autorisation de réseau local utilise une stratégie de migration d'autorisation fractionnée pour gérer différemment les applications nouvelles et héritées, en fonction de leur SDK cible.

Catégorie Niveau du SDK cible Comportement d'accès au réseau local Action requise du développeur
Nouvelles applications / applications mises à jour >= 37 (Android 17) Bloqué par défaut Déclarez et demandez l'autorisation d'exécution ACCESS_LOCAL_NETWORK
Anciennes applications < 37 Les applications disposant de l'autorisation INTERNET reçoivent une autorisation implicite pour ACCESS_LOCAL_NETWORK, ce qui leur permet de conserver l'accès. Cette autorisation est temporaire et sera bloquée par défaut une fois que l'application aura atteint le SDK cible 37 Aucune modification de code immédiate n'est nécessaire. Ne demandez pas ACCESS_LOCAL_NETWORK lors de l'exécution avant de cibler le SDK 37.

Stratégie LNP par cas d'utilisation

  • Diffusion : pour les fonctionnalités de diffusion de contenus multimédias, la stratégie la plus appropriée et la plus respectueuse de la confidentialité consiste à utiliser le sélecteur de sortie. Cette méthode permet au système de gérer la découverte et la connexion au réseau local au nom de l'utilisateur, ce qui élimine la nécessité pour l'application de demander ACCESS_LOCAL_NETWORK l'autorisation.

  • Navigateurs : la gestion des erreurs nécessite différentes approches en fonction du protocole. Les erreurs UDP entraînent le code d'erreur EPERM. Pour les connexions TCP, les navigateurs doivent utiliser l'API NDK android_getnetworkblockedreason(int sockFd) pour déterminer si un paquet a été bloqué par LNP. Cette API renvoie ANDROID_NETWORK_BLOCKED_REASON_LNP.

  • Autres cas d'utilisation (par exemple, IoT) : les applications qui trouvent des appareils à l'aide de mDNS doivent utiliser android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKER, ce qui permet de trouver des appareils sans autorisation, et NsdManager#registerServiceInfoCallback / NsdManager#resolveService pour obtenir des adresses IP. Les connexions aux adresses IP obtenues de cette manière ne nécessitent pas l'autorisation ACCESS_LOCAL_NETWORK.

Pour les applications qui nécessitent une communication directe sur le réseau local et qui ne peuvent pas utiliser de sélecteurs gérés par le système, l'approche suggérée consiste à utiliser la stratégie de compteur de réinitialisation des autorisations lorsque vous ciblez Android 17 (SDK 37) ou une version ultérieure. Si l' ACCESS_LOCAL_NETWORK autorisation est révoquée par l'utilisateur, ce mécanisme offre à l'application des possibilités supplémentaires de demander à nouveau l'autorisation, ce qui permet aux développeurs de présenter une justification plus claire à l'utilisateur.

Conseils pour Android 16

Pour activer les restrictions de réseau local, procédez comme suit :

  1. Flashez votre appareil avec une version Android 16 bêta 3 ou ultérieure.
  2. Installez l'application à tester.
  3. Activez/désactivez la configuration Appcompat à l'aide d'adb.

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. Redémarrez l'appareil.

L'accès de votre application au réseau local est désormais limité, et toute tentative d'accès au réseau local entraîne des erreurs de socket. Si vous utilisez des API qui effectuent des opérations de réseau local en dehors du processus de votre application (par exemple, NsdManager), elles ne sont pas affectées lors de l'activation.

Pour rétablir l'accès, vous devez accorder à votre application l'autorisation NEARBY_WIFI_DEVICES.

  • Assurez-vous que l'application déclare l'autorisation NEARBY_WIFI_DEVICES dans son manifest.
  • Accédez à Paramètres > Applications > [Nom de l'application] > Autorisations > Appareils à proximité > Autoriser.

L'accès de votre application au réseau local devrait maintenant être rétabli, et tous vos scénarios devraient fonctionner comme avant l'activation de l'application. Voici l'impact sur le trafic réseau de l'application.

Autorisation Requête LAN sortante Requête Internet sortante/entrante Requête LAN entrante
Accordé YouTube YouTube YouTube
Refusé Gags YouTube Gags

Utilisez la commande suivante pour désactiver la configuration Appcompat :

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

Erreurs

Si une demande d'accès au réseau local échoue en raison d'une autorisation manquante :

  • Les connexions TCP entraînent généralement une erreur de délai avant expiration.

  • Les erreurs UDP et les refus d'autorisation généraux entraînent généralement un code d'erreur EPERM.

Bugs

Signalez les bugs et envoyez des commentaires pour les éléments suivants :

  • Écarts dans l'accès au réseau local (vous ne pensez pas qu'un certain accès doit être considéré comme un accès au "réseau local")
  • Bugs où l'accès au réseau local devrait être bloqué, mais ne l'est pas
  • Bugs où l'accès au réseau local ne devrait pas être bloqué, mais l'est

Ce changement ne devrait pas affecter les éléments suivants :

  • Accès à Internet
  • Réseau mobile