Al usar el protocolo OAuth, necesita una cadena secreta obtenida del servicio al que desea delegar. Si está haciendo esto en una aplicación web, simplemente puede almacenar el secreto en su base de datos o en el sistema de archivos, pero ¿cuál es la mejor manera de manejarlo en una aplicación móvil (o una aplicación de escritorio para el caso)?
Almacenar la cadena en la aplicación obviamente no es bueno, ya que alguien podría encontrarlo fácilmente y abusar de él.
Otro enfoque sería almacenarlo en su servidor y hacer que la aplicación lo recupere en cada ejecución, sin almacenarlo nunca en el teléfono. Esto es casi tan malo, porque tienes que incluir la URL en la aplicación.
La única solución viable que se me ocurre es obtener primero el token de acceso de forma normal (preferiblemente usando una vista web dentro de la aplicación), y luego enrutar todas las comunicaciones adicionales a través de nuestro servidor, lo que agregaría el secreto a los datos solicitados y se comunicaría con el proveedor Por otra parte, soy un novato en seguridad, así que realmente me gustaría escuchar las opiniones de algunas personas conocedoras sobre esto. No me parece que la mayoría de las aplicaciones lleguen a estas longitudes para garantizar la seguridad (por ejemplo, Facebook Connect parece asumir que usted pone el secreto en una cadena directamente en su aplicación).
Otra cosa: no creo que el secreto esté involucrado en solicitar inicialmente el token de acceso, por lo que podría hacerse sin involucrar a nuestro propio servidor. ¿Estoy en lo correcto?
Respuestas:
Sí, este es un problema con el diseño de OAuth al que nos enfrentamos. Optamos por proxy todas las llamadas a través de nuestro propio servidor. OAuth no estaba completamente descartado con respecto a las aplicaciones de escritorio. No hay una solución perfecta para el problema que he encontrado sin cambiar OAuth.
Si lo piensa y hace la pregunta de por qué tenemos secretos, es principalmente para el suministro y la desactivación de aplicaciones. Si nuestro secreto se ve comprometido, entonces el proveedor solo puede revocar toda la aplicación. Como tenemos que incrustar nuestro secreto en la aplicación de escritorio, estamos un poco jodidos.
La solución es tener un secreto diferente para cada aplicación de escritorio. OAuth no facilita este concepto. Una forma es que el usuario vaya y cree un secreto por su cuenta e ingrese la clave por su cuenta en su aplicación de escritorio (algunas aplicaciones de Facebook hicieron algo similar durante mucho tiempo, haciendo que el usuario fuera y creara Facebook para configurar sus presupuestos personalizados y mierda). No es una gran experiencia para el usuario.
Estoy trabajando en la propuesta de un sistema de delegación para OAuth. El concepto es que, utilizando nuestra propia clave secreta que obtenemos de nuestro proveedor, podríamos emitir nuestro propio secreto delegado a nuestros propios clientes de escritorio (uno para cada aplicación de escritorio básicamente) y luego, durante el proceso de autenticación, enviamos esa clave al nivel superior proveedor que nos llama y vuelve a validar con nosotros. De esa manera, podemos revocar los secretos que emitimos para cada cliente de escritorio. (Tomando prestado mucho de cómo funciona esto desde SSL). Todo este sistema sería perfecto para los servicios web de valor agregado y para transmitir llamadas a un servicio web de terceros.
El proceso también podría realizarse sin devoluciones de llamadas de verificación de delegación si el proveedor de nivel superior proporciona una API para generar y revocar nuevos secretos delegados. Facebook está haciendo algo similar al permitir que las aplicaciones de Facebook permitan a los usuarios crear sub-aplicaciones.
Hay algunas conversaciones sobre el tema en línea:
http://blog.atebits.com/2009/02/fixing-oauth/ http://groups.google.com/group/twitter-development-talk/browse_thread/thread/629b03475a3d78a1/de1071bf4b820c14#de1071bf4b820c14
La solución de Twitter y Yammer es una solución de pin de autenticación: https://dev.twitter.com/oauth/pin-based https://www.yammer.com/api_oauth_security_addendum.html
fuente
Con OAUth 2.0, puede almacenar el secreto en el servidor. Use el servidor para adquirir un token de acceso que luego moverá a la aplicación y podrá hacer llamadas desde la aplicación al recurso directamente.
Con OAuth 1.0 (Twitter), se requiere el secreto para realizar llamadas API. Proxying llamadas a través del servidor es la única manera de garantizar que el secreto no se vea comprometido.
Ambos requieren algún mecanismo que el componente de su servidor sepa que es su cliente quien lo llama. Esto tiende a hacerse durante la instalación y el uso de un mecanismo específico de la plataforma para obtener una identificación de aplicación de algún tipo en la llamada a su servidor.
(Soy el editor de la especificación OAuth 2.0)
fuente
Una solución podría ser codificar el secreto de OAuth en el código, pero no como una cadena simple. Ofuscarlo de alguna manera - dividirlo en segmentos, cambiar los caracteres por un desplazamiento, rotarlo - hacer alguna o todas estas cosas. Un cracker puede analizar su código de bytes y encontrar cadenas, pero el código de ofuscación puede ser difícil de entender.
No es una solución infalible, sino barata.
Dependiendo del valor del exploit, algunos crackers geniales pueden hacer todo lo posible para encontrar su código secreto. Debe sopesar los factores: el costo de la solución del servidor mencionada anteriormente, el incentivo para que los crackers gasten más esfuerzos en encontrar su código secreto y la complejidad de la ofuscación que puede implementar.
fuente
No almacene el secreto dentro de la aplicación.
Debe tener un servidor al que pueda acceder la aplicación a través de https (obviamente) y almacenar el secreto en él.
Cuando alguien desea iniciar sesión a través de su aplicación móvil / de escritorio, su aplicación simplemente reenviará la solicitud al servidor que luego agregará el secreto y lo enviará al proveedor de servicios. Su servidor puede decirle a su aplicación si tuvo éxito o no.
Luego, si necesita obtener información confidencial del servicio (Facebook, Google, Twitter, etc.), la aplicación pregunta a su servidor y su servidor se la dará a la aplicación solo si está correctamente conectada.
Realmente no hay ninguna opción, excepto almacenarla en un servidor. Nada del lado del cliente es seguro.
Nota
Dicho esto, esto solo lo protegerá contra un cliente malintencionado, pero no contra un cliente malintencionado y no contra otros clientes maliciosos (phishing) ...
OAuth es un protocolo mucho mejor en el navegador que en el escritorio / móvil.
fuente
Hay una nueva extensión para el Tipo de concesión de código de autorización llamada Clave de prueba para el intercambio de código (PKCE) . Con él, no necesitas un secreto de cliente.
de https://oauth.net/2/pkce/
Para obtener más información, puede leer el RFC 7636 completo o esta breve introducción .
fuente
Aquí hay algo para pensar. Google ofrece dos métodos de OAuth ... para aplicaciones web, donde registra el dominio y genera una clave única, y para aplicaciones instaladas donde utiliza la clave "anónimo".
Tal vez he pasado por alto algo en la lectura, pero parece que compartir la clave única de su aplicación web con una aplicación instalada es probablemente más seguro que usar "anónimo" en el método oficial de aplicaciones instaladas.
fuente
Con OAuth 2.0 simplemente puede usar el flujo del lado del cliente para obtener un token de acceso y luego usar este token de acceso para autenticar todas las solicitudes adicionales. Entonces no necesitas un secreto en absoluto.
Puede encontrar una buena descripción de cómo implementar esto aquí: https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#mobile-apps
fuente
No tengo mucha experiencia con OAuth, pero ¿no todas las solicitudes requieren no solo el token de acceso del usuario, sino también una clave y secreto de consumidor de la aplicación? Entonces, incluso si alguien roba un dispositivo móvil e intenta extraer datos de él, necesitaría una clave de aplicación y un secreto para poder hacer cualquier cosa.
Siempre pensé que la intención detrás de OAuth era que cada Tom, Dick y Harry que tuvieran un mashup no tuvieran que almacenar sus credenciales de Twitter en claro. Creo que resuelve ese problema bastante bien a pesar de sus limitaciones. Además, en realidad no fue diseñado con el iPhone en mente.
fuente
Estoy de acuerdo con Felixyz. OAuth, aunque es mejor que la autenticación básica, todavía tiene un largo camino por recorrer para ser una buena solución para aplicaciones móviles. He estado jugando con el uso de OAuth para autenticar una aplicación de teléfono móvil en una aplicación de Google App Engine. El hecho de que no pueda administrar de manera confiable el secreto del consumidor en el dispositivo móvil significa que lo predeterminado es usar el acceso 'anónimo'.
El paso de autorización del navegador de la implementación de Google App Engine OAuth lo lleva a una página donde contiene texto como: "El sitio <some-site> solicita acceso a su cuenta de Google para los productos enumerados a continuación"
YourApp (yourapp.appspot.com): no está afiliado a Google
etc.
Toma <some-site> del dominio / nombre de host utilizado en la URL de devolución de llamada que proporcione, que puede ser cualquier cosa en Android si utiliza un esquema personalizado para interceptar la devolución de llamada. Entonces, si usa el acceso 'anónimo' o su secreto de consumidor está comprometido, entonces cualquiera podría escribir un consumidor que engañe al usuario para que le dé acceso a su aplicación gae.
La página de autorización de Google OAuth también contiene muchas advertencias que tienen 3 niveles de gravedad dependiendo de si está usando 'anónimo', secreto del consumidor o claves públicas.
Cosas bastante aterradoras para el usuario promedio que no es técnicamente inteligente. No espero tener un alto porcentaje de finalización de registro con ese tipo de cosas en el camino.
Esta publicación de blog aclara cómo los secretos del consumidor realmente no funcionan con las aplicaciones instaladas. http://hueniverse.com/2009/02/should-twitter-discontinue-their-basic-auth-api/
fuente
También estoy tratando de encontrar una solución para la autenticación móvil OAuth y almacenar secretos dentro del paquete de aplicaciones en general.
Y una idea loca simplemente me golpeó: la idea más simple es almacenar el secreto dentro del binario, pero ofuscado de alguna manera, o, en otras palabras, almacenar un secreto cifrado. Entonces, eso significa que tienes que almacenar una clave para descifrar tu secreto, lo que parece habernos cerrado el círculo. Sin embargo, ¿por qué no usar una clave que ya está en el sistema operativo?
Entonces, para aclarar mi idea es que eliges una cadena definida por el sistema operativo, no importa cuál. Luego, encripte su secreto usando esta cadena como clave y guárdela en su aplicación. Luego, durante el tiempo de ejecución, descifre la variable usando la clave, que es solo una constante del sistema operativo. Cualquier hacker que eche un vistazo a su binario verá una cadena encriptada, pero ninguna clave.
¿Eso funcionará?
fuente
Aquí tengo la forma segura de almacenar su información de oAuth en la aplicación móvil
https://stackoverflow.com/a/17359809/998483
https://sites.google.com/site/greateindiaclub/mobil-apps/ios/securelystoringoauthkeysiniosapplication
fuente
Facebook no implementa OAuth estrictamente hablando (todavía), pero ha implementado una forma para que no incruste su secreto en la aplicación de su iPhone: https://web.archive.org/web/20091223092924/http://wiki. developers.facebook.com/index.php/Session_Proxy
En cuanto a OAuth, sí, cuanto más lo pienso, estamos un poco llenos. Quizás esto lo arregle.
fuente
Ninguna de estas soluciones impide que un hacker determinado detecte paquetes enviados desde su dispositivo móvil (o emulador) para ver el secreto del cliente en los encabezados http.
Una solución podría ser tener un secreto dinámico que esté formado por una marca de tiempo cifrada con una clave y algoritmo de cifrado de 2 vías privado. El servicio descifra el secreto y determina si la marca de tiempo es +/- 5 minutos.
De esta forma, incluso si el secreto se ve comprometido, el hacker solo podrá usarlo durante un máximo de 5 minutos.
fuente
Como otros han mencionado, no debería haber ningún problema real con el almacenamiento local del secreto en el dispositivo.
Además de eso, siempre puede confiar en el modelo de seguridad basado en UNIX de Android: solo su aplicación puede acceder a lo que escribe en el sistema de archivos. Simplemente escriba la información en el objeto SharedPreferences predeterminado de su aplicación.
Para obtener el secreto, uno tendría que obtener acceso de root al teléfono Android.
fuente