martes, junio 24, 2014

No pongas tus tokens oAuth en tus apps para Andorid

Cuando los investigadores de la Universidad de Columbia publicaron su trabajo referente a PlayDrone, una de las cosas que más revuelo causó fue su aviso sobre la cantidad de apps que están guardando sus tokens OAuth y sus API Keys de Amazon directamente en las apps.

Figura 1: Número de tokens por tipo descubiertos en apps de Google Play

En el artículo de The Register, los mismos autores del trabajo decían que Google estaba trabajando en añadir una alerta que avise a un desarrollador cuando una de sus apps lleve hardcodeado uno de estos tokens, para que sea consciente del riesgo que corre.

Para encontrar esos tokens, no es necesario ni irse a Google Play a buscar las apps y decompilarlas, ya que simplemente haciendo un poco de hacking con buscadores en los repositorios de código habituales es más que suficiente para localizar códigos fuentes con el OAuth_Token y el OAuth_Token_Secret a la vista de cualquiera. Algo similar a cuando se buscan bugs en repositorios de código open source.

Figura 2: Tokens OAuth publicados en repositorios de código

Al final, cuando se da un OAuth_Token y un OAuth_Token_Secret a una app se le está concediendo una especie de contraseña que da acceso a una cuenta con una lista de permisos. Esos permisos pueden ser acceder a información personal, hacer una publicación, hacer un follow a otra persona de una red social, dar un like, acceder a la lista de contactos, leer y escribir mensajes privados, etcétera. 

Cuando se pone un token OAuth en una app que va a ser instalada en miles de dispositivos, se está dando un acceso común a una misma cuenta a todos los dispositivos que hayan descargado y ejecutado esa app, lo que no parece tener mucho sentido. Si uno de esos comienza a hacer un mal uso del token, la única forma de detenerlo será generar un nuevo token y desplegar una nueva versión de la app, algo que va contra cualquier sentido común.

Figura 3: Esquema de gestión centralizada server-side del token de acceso a cuenta

Si se quiere que desde una app que está instalada en muchos dispositivos se pueda hacer cosas en una cuenta por medio de un token OAuth, lo suyo es crear un servicio que controle el uso del token y que monitorice qué es lo que quiere hacer cada usuario con la cuenta. Así, si uno de los usuarios comienza a hacer un uso malicioso o simplemente no autorizado, se puede restringir su acceso.

Si pones los tokens en las apps, o se los envías, o cualquier otra cosa que acabe con que muchas apps instaladas en clientes acaben teniendo el mismo token, ya sabes a todos los riesgos que te expones. Si vas a hacer una app para subir a Google Play, antes aprende buenas prácticas de desarrollo seguro de apps para Android.

Saludos Malignos!

8 comentarios:

jordi.ferran dijo...

Excelente artículo, muy buenas observaciones. Una evidencia que las herramientas para hacer el bien, pueden hacer mal tan solo con la ignorancia del propio programador. La mayor part del software falla por su propio diseño.

Unknown dijo...

Pues en el libro "Desarrollo de aplicaciones seguras" que comentas, en el proyecto que se desarrolla al final del libro los tokens para conectarse con dropbox aparecen hardcoded en el código, página 238. Supongo que una correcta implementación de como gestionar esos tokens estaría bien para los que hemos comprado el libro.
Saludos

Miguel Angel dijo...

Hola Aitzol,

En el libro "Desarrollo de aplicaciones seguras" no se abordan buenas prácticas para la gestión de sesiones OAuth. Efectivamente, en el Anexo del libro aparecen las keys de OAuth para Dropbox hardcodeadas, lo cual no es una buena práctica en absoluto por las razones que se exponen en el post.

Creo que una buena solución para evitar tener que escribir las claves en el código sería pedirlas a un web service o derivar la lógica y la gestión a dicho servicio, tal como indica Chema en el post. Por supuesto, sería fundamental cifrar las peticiones contra ese servicio por https e incluso implementar alguna capa de cifrado más mediante hmac... de esta forma evitas que alguien pueda falsear las peticiones al servicio y obtener las claves.

Saludos!

Unknown dijo...

Hola Miguel Angel,

No logro visualizar el workflow para derivar la gestión de claves a un servicio web. Te propongo un ejemplo:

- Una aplicación que usa un tercero (twitter, facebook, google...) para gestionar el login
- Estos proveedores me exigen crear una aplicación en su plataforma y utilizar el par de claves oatuh para autenticarme. POr tanto necestito conocer el par de tokens para iniciar la autenticación.

- Si no los tengo en la aplicación y lo delego a un web service, tengo que habilitar un endpoint para que devuelva el par de tokens. Por supuesto esta petición ha de responder a usuarios anónimos, ya que todavía no he podido autenticar al usuario.

- Entonces, cualquiera que conozca la url del endpoint podría recuperar mis claves, y suplantar mi aplicación (el cifrado no arregla este problema)

Estoy implementando una app con este esquema, y de momento, las claves están en el código. Aunque estoy a tiempo de cambiar el esquema.

Desconozco la capa de cifrado por hmac, ¿arreglaría el problema?

Podrías mostrarme un workflow seguro para el escenario que estoy planteando.

Saludos

Miguel Angel dijo...
Este comentario ha sido eliminado por el autor.
Miguel Angel dijo...

Buenas Aitzol,

Creo que para tu problema lo mejor sería que derivases toda la lógica de OAuth a tu web service. De esta forma nunca expones las keys.

Tu workflow (con Facebook por ejemplo) sería el siguiente:

1- Cliente móvil pide registro a través de Facebook a tu web service.

2- Web service inicia proceso de autenticación contra Facebook mediante OAuth con los famosos tokens.

3- Facebook pide credenciales de usuario. Tu web service las solicita al cliente móvil.

4- El cliente móvil envía dichas credenciales a tu web service mediante una comunicación cifrada por https. Tu web service no las debería almacenar o si lo hace deberían estar encriptadas.

5- Tu web service realiza la autenticación contra Facebook y envía la respuesta o la sesión al cliente móvil...

Dime si te puede servir esta solución...

Saludos!

Unknown dijo...

Hola Miguel Angel,

Creo que podría valer,tengo que analizarlo en detalle. Complica un poco el workflow pero creo que merece la pena.

Un saludo

Yerry dijo...

Chema este error ya se ha solucionado, te pregunto para cuando cuente de este problema tenga la respuesta.

Entrada destacada

10 maneras de sacarle el jugo a tu cuenta de @MyPublicInbox si eres un Perfil Público

Cuando doy una charla a algún amigo, conocido, o a un grupo de personas que quieren conocer MyPublicInbox , siempre se acaban sorprendiendo ...

Entradas populares