Cualquier app que tenga el permiso INTERNET puede acceder a los dispositivos de una red de área local (LAN).
Esto facilita que las apps se conecten a dispositivos locales, pero también tiene implicaciones para la privacidad, como la formación de una huella digital del usuario y la posibilidad de actuar como proxy de la ubicación.
El proyecto de Protecciones de red local tiene como objetivo proteger la privacidad del usuario limitando el acceso a la red local detrás de un nuevo permiso de tiempo de ejecución.
Impacto
Durante Android 16, este permiso es una función opcional, lo que significa que solo se verán afectadas las apps que lo habiliten. El objetivo de la habilitación es que los desarrolladores de apps comprendan qué partes de sus apps dependen del acceso implícito a la red local para que puedan prepararse para protegerlas con permisos en una versión futura de Android.
Las apps se verán afectadas si acceden a la red local del usuario con los siguientes métodos:
- Uso directo o de biblioteca de sockets sin procesar en direcciones de red locales, por ejemplo,
Multicast DNS (mDNS)oSimple Service Discovery Protocol (SSDP) - Uso de clases a nivel del framework que acceden a la red local, por ejemplo,
NsdManager.
Detalles del impacto
El tráfico hacia y desde una dirección de red local requiere permiso de acceso a la red local. En la siguiente tabla, se enumeran algunos casos comunes:
| Operación de red de bajo nivel de la app | Se requiere permiso de red local |
|---|---|
| Cómo realizar una conexión TCP saliente | sí |
| Cómo aceptar una conexión TCP entrante | sí |
| Envía una transmisión unidifusión, multidifusión o difusión de UDP | sí |
| Recepción de una transmisión unidifusión, multidifusión o difusión de UDP entrante | sí |
Estas restricciones se implementan en lo más profundo de la pila de redes y, por lo tanto, se aplican a todas las APIs de redes. Esto incluye los sockets creados en la plataforma o el código administrado, las bibliotecas de redes como Cronet y OkHttp, y cualquier API implementada sobre ellos. Intentar resolver servicios en la red local que tienen un sufijo .local requiere permiso de red local.
Excepciones a las reglas anteriores:
- Si el servidor DNS de un dispositivo está en una red local, el tráfico hacia él y desde él (en el puerto 53) no requiere permiso de acceso a la red local.
- Las aplicaciones que usen el Selector de salida como selector integrado en la app no necesitarán permisos de red local (se proporcionará más orientación en una versión posterior).
Aplicación de Android 17
A partir de Android 17, las protecciones de red local son obligatorias y se aplican a las apps segmentadas para Android 17 o versiones posteriores.
| Aspecto | Android 16 | Android 17 |
|---|---|---|
| SDK de destino | 36 | 37 o más |
| Permiso | NEARBY_WIFI_DEVICES usado de forma temporal | ACCESS_LOCAL_NETWORK |
| Acceso predeterminado | El acceso a la red local está abierto | La red local está bloqueada de forma predeterminada para todas las apps que actualizan su SDK de destino |
| Grupo de permisos | Forma parte del grupo de permisos NEARBY_DEVICES existente |
Para verificar que la funcionalidad de la app no se vea afectada después de la aplicación de la política, las aplicaciones que segmentan SDK 37 o versiones posteriores deben adoptar una de las siguientes opciones para administrar el acceso a la red local:
Ruta A: Uso de selectores que preservan la privacidad
Para las tareas de detección y conexión mediadas por el sistema, usa selectores para evitar solicitar el permiso de tiempo de ejecución amplio por completo. Usa los siguientes selectores según tu caso de uso:
- Transmisión de contenido multimedia: Las aplicaciones que admiten Google Cast pueden usar la función de selector de salida. Esto permite que los desarrolladores permitan a los usuarios seleccionar dispositivos de transmisión específicos sin que la app necesite solicitar el permiso amplio de
ACCESS_LOCAL_NETWORK. - Conectividad general:
NsdManagerincluye un selector de servicios ejecutado por el sistema para el descubrimiento de mDNS. En lugar de que la app analice toda la red, el sistema muestra un diálogo que permite al usuario seleccionar un solo dispositivo al que la app puede acceder.
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
}
})
Ruta B: Solicita permiso de tiempo de ejecución (acceso amplio)
Esta ruta es obligatoria para casos de uso complejos, como la automatización del hogar o la administración de dispositivos IoT, que necesitan acceso amplio y persistente a la red local.
Declara el permiso en el manifiesto: Los desarrolladores deben declarar de forma explícita
ACCESS_LOCAL_NETWORKenAndroidManifest.xml.Solicita permiso en el tiempo de ejecución: Antes de intentar acceder a la red local, las aplicaciones deben verificar si se otorgó el permiso. De lo contrario, deben llamar a
Activity.requestPermission()para activar la instrucción estándar del sistema.Situación de permiso previo: El permiso
ACCESS_LOCAL_NETWORKforma parte del grupo de permisosNEARBY_DEVICES. Si un usuario ya otorgó otro permiso en este grupo (como los permisos de Bluetooth), no se le volverá a solicitar acceso a la red local.Manejo del rechazo y la revocación: Las apps deben controlar correctamente los casos en los que el usuario rechaza la solicitud o revoca el permiso más tarde en la configuración del sistema. En estos casos, se bloqueará el tráfico de la red local.
Estrategia de contador de restablecimiento de solicitudes de permisos
La plataforma implementa una estrategia de restablecimiento del contador que aborda situaciones en las que la denegación previa de una app del grupo de permisos NEARBY_DEVICES (que ahora incluye ACCESS_LOCAL_NETWORK) impidió que la app solicitara el permiso después de presentar adecuadamente su justificación. Este mecanismo otorga oportunidades adicionales para que la app invoque la API de requestPermission(), lo que restablece de manera efectiva el recuento de rechazos del permiso de ACCESS_LOCAL_NETWORK. Esto permite un mayor nivel de matices en el reenganche con el usuario, en especial cuando el rechazo inicial se produjo antes de que la app pudiera transmitir la necesidad de acceder a la red local para su funcionalidad principal.
Modelo de permisos divididos
El permiso de red local utiliza una estrategia de migración de permisos divididos para controlar las aplicaciones nuevas y heredadas de manera diferente, según su SDK de destino.
| Categoría | Nivel del SDK de destino | Comportamiento del acceso a la red local | Acción obligatoria del desarrollador |
|---|---|---|---|
| Apps nuevas y actualizadas | >= 37 (Android 17) | Bloqueado de forma predeterminada | Declara y solicita el permiso de tiempo de ejecución ACCESS_LOCAL_NETWORK |
| Apps heredadas | < 37 | Las apps con permiso de INTERNET reciben un permiso implícito para ACCESS_LOCAL_NETWORK, lo que les permite conservar el acceso. Esto es temporal y se bloqueará de forma predeterminada una vez que la app actualice el SDK de destino a la versión 37. |
No es necesario realizar cambios en el código de inmediato |
Estrategia de LNP por caso de uso
Transferencia: Para las funciones de transferencia de contenido multimedia, la estrategia más adecuada y que preserva la privacidad es usar el conmutador de salida. Este método permite que el sistema controle la detección y la conexión de redes locales en nombre del usuario, lo que elimina la necesidad de que la app solicite el permiso de
ACCESS_LOCAL_NETWORK.Navegadores: El manejo de errores requiere diferentes enfoques según el protocolo. Los errores de UDP generan el código de error
EPERM. Para las conexiones TCP, los navegadores deben usar la API del NDKandroid_getnetworkblockedreason(int sockFd)para determinar si LNP bloqueó un paquete. Esta API devuelveANDROID_NETWORK_BLOCKED_REASON_LNP.Otros casos de uso (por ejemplo, IoT): Las aplicaciones que encuentran dispositivos con mDNS deben usar
android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKER, que permite encontrar dispositivos sin el permiso, yNsdManager#registerServiceInfoCallback/NsdManager#resolveServicepara obtener direcciones IP. Las conexiones a las direcciones IP obtenidas de esta manera no requieren el permisoACCESS_LOCAL_NETWORK.
En el caso de las apps que requieren comunicación directa con la red local y no pueden usar selectores mediados por el sistema, el enfoque sugerido es usar la estrategia del contador de restablecimiento de permisos. Si el usuario revoca el permiso ACCESS_LOCAL_NETWORK, este mecanismo brinda oportunidades adicionales para que la app vuelva a solicitar el permiso, lo que permite a los desarrolladores presentar una justificación más clara para el usuario.
Orientación sobre Android 16
Para habilitar las restricciones de red local, haz lo siguiente:
- Escribe en la memoria flash de tu dispositivo una compilación con Android 16 Beta 3 o versiones posteriores
- Instala la app que se probará
Cómo activar o desactivar la configuración de Appcompat con adb
adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>Reinicia el dispositivo
Ahora, el acceso de tu app a la red local está restringido, y cualquier intento de acceder a la red local genera errores de socket.
Si usas APIs que realizan operaciones de red local fuera del proceso de tu app (por ejemplo, NsdManager), no se verán afectadas durante la habilitación.
Para restablecer el acceso, debes otorgarle permiso a tu app para NEARBY_WIFI_DEVICES.
- Asegúrate de que la app declare el permiso
NEARBY_WIFI_DEVICESen sumanifest. - Ve a Configuración > Apps > [Nombre de la app] > Permisos > Dispositivos cercanos > Permitir.
Ahora se debería restablecer el acceso de tu app a la red local, y todos tus casos de uso deberían funcionar como lo hacían antes de habilitar la app. Así se ve afectado el tráfico de red de la app.
| Permiso | Solicitud de LAN saliente | Solicitud de Internet entrante o saliente | Solicitud de LAN entrante |
|---|---|---|---|
| Concedido | Works | Works | Works |
| Sin otorgar | Errores | Works | Errores |
Usa el siguiente comando para desactivar la configuración de Appcompat
adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>
Errores
Si falla una solicitud de acceso a la red local debido a que falta un permiso, haz lo siguiente:
Por lo general, las conexiones TCP generan un error de tiempo de espera.
Por lo general, los errores de UDP y los rechazos de permisos generales generan un código de error EPERM.
Errores
Envía errores y comentarios sobre lo siguiente:
- Discrepancias en el acceso a la LAN (crees que un determinado acceso no debería considerarse como acceso a la "red local")
- Errores en los que se debería bloquear el acceso a la LAN, pero no se hace
- Errores en los que no se debería bloquear el acceso a la LAN, pero se bloquea
Los siguientes elementos no deberían verse afectados por este cambio:
- Acceso a Internet
- Red móvil