Permisos innecesarios en Android aumentan los vectores de ataque

Permisos innecesarios en Android aumentan los vectores de ataque

Hoy en día Android se ha convertido en un sistema operativo muy presente en nuestras vidas. De hecho podemos encontrarlo en multitud de teléfonos, tablets, televisores, relojes, y hasta en coches. En el último congreso de desarrolladores organizado anualmente por Google (Google I/O) quedó de manifiesto la popularidad de esta plataforma al alcanzar 1 billón de usuarios activos en un periodo de 30 días.

Para responder a las necesidades de los usuarios, Android cuenta un market (Google Play) que permite la instalación de aplicaciones de terceros sin ningún tipo de restricción. Según las últimas estadísticas, el número de aplicaciones disponibles en el market es de 1,6 millones aproximadamente.

Android pone a disposición de los desarrolladores una extensa API con la que pueden interactuar con el dispositivo del usuario y acceder, por ejemplo, al hardware del mismo o a la información privada del usuario.

Sin embargo, para garantizar la privacidad y la seguridad de los usuarios, estos datos deben de estar protegidos de tal forma que los usuarios puedan: tener un control sobre su privacidad y decidir si permiten el acceso o no a las aplicaciones de terceros. Para ello Android cuenta con un sistema de permisos.

De esta forma, mientras que un desarrollador define los permisos que la aplicación necesita para su correcto funcionamiento, un usuario revisará estos permisos en tiempo de instalación y decidirá si proceder con la misma, previa aceptación de los permisos; o no, evitando posibles riesgos derivados de los permisos solicitados.

Pero, ¿realmente el desarrollador sabe con certeza los permisos mínimos que tiene que solicitar para que la aplicación funcione correctamente? ¿qué ocurriría si se llegara a solicitar permisos innecesarios? Si un usuario final llegase a instalar la aplicación, ¿podría verse afectado de alguna forma?

Permisos en Android

Tal y como se ha visto antes, Android sigue un sistema de permisos que permite a los usuarios protegerse, en tiempo de instalación, de un posible uso malintencionado por parte de aplicaciones capaces de acceder a la información sensible disponible en un dispositivo móvil.

En líneas generales, el sistema utilizado por Android se podría definir de la siguiente forma:

  1. Cada aplicación tiene asociado un conjunto de permisos, declarado en el manifest (fichero AndroidManifest.xml), que permite el acceso a determinados recursos.
  2. En el proceso de instalación no hay forma aceptar un subconjunto de permisos, sino que todos los permisos tienen que ser aceptados explícitamente. Una vez finalizado se garantiza un control total, sin restricciones, de los permisos solicitados.
  3. Finalmente los permisos se comprueban en tiempo de ejecución cuando los recursos son accedidos.

¿Qué piensan los usuarios acerca de estos permisos?

Según los datos obtenidos por algunos estudios, la mayoría de los usuarios tienden a ignorar los mensajes de aviso que se muestran en el dispositivo durante la instalación de una aplicación. Probablemente no tengan ningún interés en los permisos solicitados y lo único que quieran sea continuar con la instalación sin ser interrumpidos. Incluso aquellos usuarios más concienciados que prestan mayor atención a los permisos, suelen encontrar las descripciones de los permisos confusas y difíciles de entender.

La mayoría de los usuarios no entienden exactamente el significado de los permisos en Android

La mayoría de los usuarios no entienden exactamente el significado de los permisos en Android (fuente)

J. Kang et al. publicaron el estudio Analyzing unnecessary permissions requested by Android apps based on users’ opinions donde participaron 125 personas en una encuesta para conocer las opiniones acerca de los permisos solicitados por 234 aplicaciones populares del market de Android.

Una vez obtenidos los resultados del estudio se pudieron extraer conclusiones muy interesantes:

  • Los usuarios se encuentran más concienciados con las aplicaciones gratuitas, ya que piensan que estas piden más permisos innecesarios que las aplicaciones de pago. De hecho las aplicaciones gratuitas tienden a pedir más permisos, y estos suelen estar relacionados con la recogida de información sensible.
  • Los usuarios piensan que las aplicaciones más antiguas, aquellas que han pasado ya por varias actualizaciones, solicitan más permisos innecesarios que las aplicaciones recién lanzadas, ya sean de pago o gratuitas. Posiblemente los desarrolladores publiquen las aplicaciones con un conjunto reducido de permisos al principio (con el objetivo de conseguir todas las instalaciones posibles) y vayan incrementándolos de forma progresiva en cada actualización.
  • Observaron que los usuarios más concienciados fueron capaces de identificar con mayor precisión los permisos innecesarios presentes en cada una de las aplicaciones.

A partir de estas conclusiones pensaron que podrían ser de utilidad para construir un sistema de permisos en Android más eficaz y confiable. Por ejemplo advirtiendo a los usuarios del peligro que entrañan aquellos permisos considerados como innecesarios más frecuentes.

Aplicaciones sobre privilegiadas

Las aplicaciones sobre privilegiadas son aquellas que solicitan permisos innecesarios y por tanto violan el principio de mínimo privilegio.

Para cumplir con este principio, los desarrolladores deberían de solicitar únicamente los permisos mínimos y necesarios (ni más ni menos) para asegurar que las aplicaciones funcionan correctamente.

Permisos innecesarios en la aplicación Battery SuperCharger

Permisos innecesarios en la aplicación Battery SuperCharger (fuente)

Como se ha podido comprobar hasta ahora, los permisos innecesarios no son más que el resultado de la diferencia (permission gap) entre los permisos declarados y los que realmente usa la aplicación.

En el momento que se produce esta diferencia, tanto los vectores de ataque como los propios ataques que puedan afectar a las aplicaciones, y por consiguiente a los usuarios, se incrementan inevitablemente.

¿Por qué los permisos innecesarios son peligrosos?

Básicamente porque al infringir el principio de mínimo privilegio, el sistema de permisos en Android pierde eficacia y los beneficios que aporta quedan en entredicho.

Por una parte, estos permisos condicionan innecesariamente a los usuarios provocando que acepten permisos potencialmente peligrosos; y por otra parte, el impacto que podría provocar la explotación de una posible vulnerabilidad en una aplicación sobre privilegiada sería bastante alto.

Este impacto se puede ver mejor a través de un ejemplo:

Considérese una aplicación en Android cualquiera capaz de comunicarse con servidores remotos gracias al permiso INTERNET declarado por la misma. Además, esta aplicación cuenta con el permiso CAMERA que le permite tomar fotos sin la intervención del usuario. Sin embargo, en el código de la aplicación no se hace uso en ningún momento de este último permiso, considerándose un permiso innecesario y por tanto peligroso.

Desafortunadamente esta aplicación utiliza una librería nativa afectada por una vulnerabilidad de tipo buffer overflow cuyo exploit ha sido descubierto recientemente. Un atacante perfectamente podría explotar esta vulnerabilidad consiguiendo una ejecución arbitraria de código (en el proceso de la aplicación) que le permitiría contar con todos los permisos declarados, incluyendo el permiso innecesario CAMERA. De esta forma el atacante podría escribir el código necesario para usar la cámara, tomar fotos y enviarlas a un servidor remoto; y ejecutarlo en la aplicación vulnerable mediante la explotación del buffer overflow.

¿Los desarrolladores son conscientes de ello?

Sí que lo son. De hecho, gracias a los resultados de otro estudio que se verá al final del artículo, llegaron a la conclusión de que los desarrolladores intentan cumplir con el principio de mínimo privilegio en las aplicaciones, pero a veces caen en el error de declarar permisos innecesarios debido a la falta de documentación en la API de Android (respecto a los permisos) y a la falta de entendimiento de los desarrolladores.

Los desarrolladores intentan cumplir con el principio de mínimo privilegio para beneficiarse del sistema de permisos en Android

Los desarrolladores intentan cumplir con el principio de mínimo privilegio para beneficiarse del sistema de permisos en Android (fuente)

A continuación se explican algunas causas comunes por las que los desarrolladores declaran más permisos de la cuenta:

  • Nombres de permisos confusos. A veces los desarrolladores solicitan permisos que creen necesarios porque piensan que encajan (suenan bien) con la funcionalidad que necesitan cubrir. Por ejemplo, los permisos ACCESS_NETWORK_STATE y ACCESS_WIFI_STATE parecen muy similares tal y como suenan, pero se usan en clases distintas, y los desarrolladores suelen pedir ambos aunque solo necesiten uno de ellos.
  • Errores de concepto. Los desarrolladores suelen confundirse al solicitar permisos innecesarios cuando hacen uso de intents (elemento básico de comunicación en Android) para invocar otras aplicaciones que sí necesitan estos permisos. Por ejemplo, es muy común encontrar aplicaciones que solicitan el permiso CAMERA cuando realmente no toman fotos, sino que mandan un intent a la aplicación de la cámara para que esta realice la acción. En este caso no necesitan el permiso CAMERA ya que solo invocan a la aplicación de la cámara que realmente toma las fotos y por tanto necesita este permiso.
  • Clases que requieren distintos permisos. La mayoría de las clases pueden tener tanto métodos protegidos por permisos como métodos que no requieren de ningún tipo de permiso. En este caso los desarrolladores acaban solicitando por confusión permisos para métodos que no los necesitan cuando estos se encuentran (dentro de la misma clase) con otros métodos que sí que los necesitan.
  • Errores propagados a través de foros. Los foros resultan muy útiles para los desarrolladores cuando no tienen claro qué permisos solicitar en las aplicaciones. Sin embargo la información disponible en estos foros no siempre es fiable, haciendo que los desarrolladores copien esta información y terminen solicitando permisos innecesarios.
  • Permisos de prueba. Es posible que los desarrolladores necesiten un permiso durante la fase de pruebas (e.g., ACCESS_MOCK_LOCATION) que luego olvidan eliminar y finalmente permanece en la aplicación cuando pasa a producción.

Todo esto podría evitarse si la documentación de la API fuera más completa y existiera una clara relación entre los distintos métodos disponibles en la API (por método y no por clase) y los permisos que realmente necesitan. De esta forma se fomentaría un uso correcto de los permisos, los desarrolladores dejarían de declarar permisos innecesarios por desconocimiento o confusión, y el riesgo por el cual una aplicación podría ser comprometida se vería disminuido debido a la reducción de los vectores de ataque.

Permisos y métodos de la API, una relación necesaria

Claramente existe la necesidad de contar con una relación clara y precisa entre los métodos definidos en la API de Android y los permisos requeridos por cada uno de ellos. No cabe duda que sería un recurso muy valioso para los desarrolladores en un modelo de permisos como el de Android, sin embargo esta correspondencia como tal no existe de forma oficial 🙁

Pero, ¿por qué no está documentada esta relación entre métodos y permisos de forma detallada? Seguramente no sea una prioridad de Google, y considerando el tamaño actual de la API, la complejidad del código fuente, y las dificultades en un análisis dinámico, no debe de ser una tarea sencilla de realizar.

Estudios relacionados

Numerosos estudios se han publicado en los últimos años respecto al uso de los permisos en Android por parte de los usuarios y los desarrolladores de aplicaciones. Sin embargo, en este apartado se analiza uno de los primeros estudios en la materia (Android Permissions Demystified) presentado por A. P. Felt et al. en la conferencia de seguridad ACM CCS (Computer and Communications Security) en octubre de 2011.

Este estudio tuvo una especial relevancia ya que al definir una primera relación entre los métodos de la API y los permisos necesarios, pudo servir de referencia en varios estudios futuros.

Durante el mismo llegaron a trabajar en dos fases:

Creación de la relación (permission mapping)

Como primer paso crearon la correspondencia necesaria para averiguar los permisos que requerían cada uno de los métodos disponibles en la API actual (nivel de API 8, Android 2.2). Para ello utilizaron herramientas de testing automatizadas donde alcanzaron una cobertura de la API del 85%.

Una vez calculadas las relaciones consiguieron identificar los permisos necesarios para un total de 1.259 métodos frente a los 78 métodos cuyos permisos se localizaron en la documentación de la API, consiguiendo una mejora 16 veces superior. Respecto a los 78 anteriores, también identificaron 6 de ellos que se encontraban mal documentados.

Aunque estos datos correspondan a una API bastante antigua, todavía pueden servir de referencia a día de hoy.

Desarrollo de Stowaway

Partiendo de la relación obtenida en la fase anterior, utilizaron este conocimiento para desarrollar Stowaway, una herramienta de análisis estático capaz de detectar los permisos innecesarios de una aplicación.

Esquema general de la herramienta Stowaway (http://web.cs.ucdavis.edu/~hchen/paper/msr2013-slide.pdf)

Esquema general de la herramienta Stowaway (fuente)

Es decir, mediante un análisis estático recopilaban todas las llamadas a la API (a través de los métodos), y a continuación buscaban los permisos asociados en la relación anterior. Todos aquellos permisos que estuvieran declarados en el manifest pero no figuraran en el código se consideraban innecesarios, y por tanto la aplicación sobre privilegiada.

Una vez desarrollada la herramienta, tomaron un conjunto de 940 aplicaciones para determinar si los desarrolladores estaban siguiendo el principio de mínimo privilegio o por el contrario estaban sobre privilegiando las aplicaciones. Los resultados del análisis fueron los siguientes:

  • 1/3 de las aplicaciones analizadas violaban el principio de mínimo privilegio (sobre privilegiadas).
  • De estas aplicaciones sobre privilegiadas más de la mitad (56%) solo solicitaba 1 permiso innecesario, mientras que el 6% solicitaba más de 4.

A partir de los cuales llegaron a la conclusión, tal y como se comentó en un apartado anterior, de que los desarrolladores estaban intentando cumplir con el principio de mínimo privilegio por la baja tasa de aplicaciones sobre privilegiadas detectada, beneficiándose por ello de la eficacia del sistema de permisos presente en Android.

¿Cómo protegerse mientras tanto?

Por una parte, los desarrolladores deberían de intentar solicitar únicamente los permisos que necesiten, cumpliendo con el principio de mínimo privilegio y evitando el desarrollo de aplicaciones sobre privilegiadas. Para ello, mientras que Google no mejore la documentación de la API en este aspecto, habrá que recurrir a técnicas o herramientas de análisis que permitan comprobar si una aplicación realmente utiliza todos los permisos declarados en la misma.

De forma complementaria, los usuarios no deberían de delegar toda la responsabilidad en los desarrolladores y olvidarse de la seguridad en las aplicaciones. Ya que no todos los desarrolladores tienen las mismas intenciones, y aunque una aplicación no solicite permisos innecesarios, perfectamente podría ser maliciosa y poner al usuario en peligro.

Por ello, a continuación se indican algunas recomendaciones muy básicas que no conviene olvidar cuando se instalan aplicaciones en Android:

  • Asegurarse de descargar las aplicaciones desde fuentes seguras (aunque el market de Android no está exento de aplicaciones maliciosas).
  • Informarse sobre las aplicaciones antes de descargarlas e instalarlas: averiguando quién es el desarrollador, consultando los comentarios de otros usuarios sobre ellas, revisando la valoración en el market,…
  • Revisar detenidamente los permisos solicitados por las aplicaciones hasta que se comprendan completamente.
  • Evitar la instalación de aplicaciones que solicitan permisos innecesarios, podrían ser aplicaciones maliciosas.

Para finalizar, destacar el lanzamiento que Google hará en los próximos meses de la nueva versión de Android 6.0, también conocida como Android M (Marshmallow). Aparte de todas las mejoras en cuanto uso al de la batería y a la experiencia de usuario, Android M ha dado un gran paso en cuanto a la privacidad permitiendo una gestión granular de los permisos de cada aplicación.

Concretamente, Android M ya no pide al usuario que revise los permisos de una aplicación durante la instalación, sino que se van pidiendo (una única vez) bajo demanda a medida que el usuario utiliza la aplicación. Además, existe un gestor de permisos que permite otorgar o revocar los permisos de las aplicaciones en cualquier momento, ya sea a nivel de aplicación o de forma global a nivel de permiso (localización, cámara, micrófono,…).

Android M - Revisión de permisos en tiempo de ejecución

Android M – Revisión de permisos en tiempo de ejecución (fuente)

Android M - Gestión de permisos

Android M – Gestión de permisos (fuente)

 

Imagen del artículo: Why Does This Android App Need So Many Permissions?

Pedro Castillo
4 comentarios
  1. Miguel
    Miguel Dice:

    Muy interesante el artículo. Me surge entonces una duda como desarrollador, ¿de qué forma puedo evaluar si estoy pidiendo permisos no necesarios (sin saberlo, claro)? ¿Alguna herramienta que analice mi código y me diga qué me sobra/falta?

    Responder
  2. Pedro Castillo
    Pedro Castillo Dice:

    Hola Miguel, ¡me alegro de que te haya resultado interesante! Mientras investigaba para redactar esta entrada, me encontré con muchos estudios que analizaban esta problemática y proponían distintas soluciones; sin embargo la mayoría de ellas quedaban a nivel teórico 🙁

    A nivel práctico y por lo que conozco, Stowaway permitía precisamente lo que preguntas, pero abandonaron el proyecto (http://android-permissions.org). Una alternativa podría ser PScout, una aplicación que permite averiguar los permisos que requieren cada uno de los métodos de la API de Android. Aunque la página oficial (http://pscout.csl.toronto.edu) se encuentre caída, si haces una búsqueda en GitHub (https://github.com/search?q=pscout) podrás encontrar proyectos interesantes derivados de PScout. Concretamente hay uno que transforma la salida de PScout en XML para que pueda ser utilizado con Android Lint durante el desarrollo.

    No he llegado a utilizar estas herramientas pero espero que puedan resultarte útiles como punto de partida 🙂

    Responder
  3. Jamtorres
    Jamtorres Dice:

    Buen artículo Pedro, ¡enhorabuena! El próximo que te sugiero para complementar este, podría ser una prueba de concepto sobre un permission redelegation attack. Crear una apk que accede a información sensible (por ejemplo los contactos) sin tener el permiso declarado a través de una apk que si que tiene ese permiso. (Yo tengo mi apuesta 🙂 ) Por último buscar apks en el market oficial que accedan a recursos críticos sin filtrar los intents, seguro que si 🙂

    Responder

Dejar un comentario

¿Quieres unirte a la conversación?
Siéntete libre de contribuir!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *