¿Es seguro usar un mecanismo de autorización sin estado donde la contraseña clara está almacenada en el llavero?

5

¿Es seguro usar el siguiente mecanismo de autorización sin estado entre un cliente (iOS y Android) y el servidor?

Registrarse

  1. El cliente proporciona un correo electrónico y una contraseña y guarda la contraseña clara en el Keychain de iOS y usa alternativa para Android.

  2. El servidor comprueba la seguridad de la contraseña si se considera lo suficientemente fuerte como para que el usuario se cree en la base de datos.

  3. El servidor genera un JWT token y lo devuelve al cliente. El token tiene un tiempo de caducidad de 15 minutos.

  4. El cliente almacena el token (tal vez en el mismo Keychain ) y lo incluye para cada solicitud siguiente en el encabezado Authorization .

  5. Para cada solicitud, el servidor comprueba el token proporcionado (comprueba la firma y el tiempo de caducidad). Si está bien, la solicitud se procesa, de lo contrario, se devuelve un HTTP 401 .

Iniciar sesión

  1. Cuando el cliente recibe un HTTP 401 del servidor, significa que se requiere un inicio de sesión. Entonces, la aplicación accede al Keychain y recibe el correo electrónico & contraseña y la envía al servidor (no es necesaria la intervención del usuario).

  2. El servidor valida las credenciales proporcionadas y, si son válidas, repetirá los pasos Registrarse del 3 al 5.

Gracias al tiempo de caducidad en el token, si un token está comprometido, será válido durante un breve período de tiempo.

Si un usuario ha iniciado sesión en varios dispositivos y cambia su contraseña de un dispositivo, los otros dispositivos se mantendrán registrados solo durante un breve período de tiempo, pero la contraseña clara almacenada en Keychain ya no será válida. Por lo tanto, se requerirá un nuevo inicio de sesión manual, lo cual creo que está bien.

¿Qué inconvenientes ve?

He estado pensando en usar actualizar token refresh token solo se usa una vez). Y por lo que he visto, almacenar la contraseña clara en el KeyChain es lo suficientemente seguro:

Documentación de los servicios de KeyChain

¿Cuál es la mejor manera? mantener las credenciales de inicio de sesión en iOS?

Pero también he visto otras preguntas que no recomiendan almacenar contraseñas en el dispositivo.

Así que me gustaría escuchar las opiniones de otros sobre esto.

    
pregunta ilopezluna 20.06.2018 - 13:28
fuente

2 respuestas

1
  

¿Qué inconvenientes ves?

Los inconvenientes que veo tienen que ver principalmente con lo que no se indica explícitamente en la pregunta en lugar de lo que se afirma explícitamente. En general, no ha indicado a qué tipo de atacante le interesa protegerse. ¿Un atacante husmeando en una red local? ¿Un atacante local?

  

El cliente proporciona un correo electrónico y una contraseña y guarda la contraseña clara en el llavero de iOS y utiliza alguna alternativa para Android.

Bien, supongamos que no nos preocupa que un atacante / proceso local (la misma máquina) que ya ha encendido nuestro teléfono. Si estuviéramos preocupados por este tipo de ataque, también podríamos usar un dispositivo físico MFA (RSA fob o lo que sea). En este caso, no estoy especialmente preocupado por los datos en reposo en el teléfono ...

  

El servidor comprueba la seguridad de la contraseña si se considera lo suficientemente fuerte como para crear el usuario en la base de datos.

¿Cómo llegó la contraseña del cliente al servidor? Si va del cliente al servidor a través de https, entonces las cosas deberían estar bien. Si se envía sin cifrar, entonces eso es algo malo .

¿Cómo hace la comprobación el servidor? ¿Cuál es la contraseña que se está verificando con ? El servidor no debe almacenar una copia de texto simple de la contraseña, sino que el servidor solo debe almacenar un hash criptográficamente seguro de la contraseña (solo use bcrypt).

Además, ¿el servidor está haciendo la comprobación de resistencia cada vez? ¿Por qué? Solo hash y compáralo con el hash almacenado.

  

El servidor genera un token JWT y lo devuelve al cliente. El token tiene un tiempo de caducidad de 15 minutos.

Una vez más, todos los datos en tránsito deben estar cifrados, incluido, por supuesto, el token JWT. Según la actualización, estamos usando HTTPS, siempre que el canal TLS sea realmente seguro, no debería haber ningún problema (ya que estamos ignorando a un atacante local como se indica anteriormente).

Por otro lado, si existe la posibilidad de que el token JWT pueda ser robado, entonces se aplican otras consideraciones. Por ejemplo, debe asegurarse de que la clave que se usa para firmar el token JWT sea lo suficientemente compleja como para que no se pueda forzar bruta.

  

Iniciar sesión

     

Cuando el cliente recibe un HTTP 401 del servidor, significa que se requiere un inicio de sesión. Así que la aplicación accede al Llavero y recibe el correo electrónico & contraseña y la envía al servidor (no es necesaria la intervención del usuario).

¿El cliente solo se conecta a un servidor conocido? ¿Cómo se identifica el servidor? ¿Es solo a través de un nombre de dominio? ¿Qué es lo que alguien hace del dominio o se mete con el archivo de hosts? Además, ¿qué pasa si hay un hombre en el medio que envía el 401, recibirá el correo electrónico y la contraseña como lo haría el servidor?

Actualización : según los comentarios, se está utilizando HTTPS.

Como tal, el cliente y el servidor se comunican utilizando un canal protegido a través de TLS. El servidor (configurado por usted, presumiblemente) envía un certificado al cliente. Este certificado contiene información que identifica el servidor, así como la clave pública del servidor. Sin embargo, no hay ninguna razón por la que deba confiar en este certificado a menos que esté firmado por una parte en la que confíe (y cuyo certificado ya haya incorporado en el almacén de confianza del dispositivo cliente, que se utiliza para verificar la firma). Por ejemplo, el certificado del servidor podría ser interceptado y reemplazado por un atacante MITM.

Por lo tanto, para tener un canal HTTPS seguro, necesita el certificado de su servidor firmado por un tercero que ya sea conocido y de confianza para la máquina cliente. Por ejemplo, para Apple hay una lista de partes confiables ( enlace ).

Dado que también (presumiblemente) está escribiendo la aplicación cliente, también puede incrustar el certificado conocido o la clave pública en la propia aplicación y confirmar el certificado del servidor contra el certificado incrustado. Esto se llama fijación de certificados.

También puede considerar el uso de HTTP Strict Transport Security para aumentar aún más la seguridad de la aplicación.

    
respondido por el hft 26.06.2018 - 05:48
fuente
1

Esta es una pregunta bien formulada y, como se plantea la pregunta en sí misma, incluso los expertos tendrán opiniones diferentes en el contexto de los marcos de seguridad absolutos / abstractos.

La realidad matizada, por supuesto, es que no hay "absolutamente seguros", solo diversos grados de inseguros, rangos de los cuales pueden ser más o menos apropiados en cualquier situación específica.

En ausencia de información adicional, algunas preguntas de puntos de partida para ayudar a generar ideas / modelar amenazas:

  • ¿Qué datos protegen estas credenciales?

    En un extremo del espectro, la aplicación podría ser un juego, las credenciales protegen el estado del juego no sensible. En el otro extremo, las credenciales podrían proteger la información médica confidencial.

  • ¿Quiénes son tus usuarios?

    ¿Sus usuarios son personas poco sofisticadas que pueden usar la misma contraseña en muchos servicios, incluido el suyo?

    ¿Podrían sus usuarios ser miembros de un grupo identificable que puede estar más o menos sujeto a que sus dispositivos se vean comprometidos / buscados / clonados (por ejemplo, periodistas, personal corporativo de alto nivel)?

  • ¿Qué puede pasar con los usuarios individuales y su comunidad como resultado de un compromiso?

    ¿Puede un actor que comprometa la cuenta de un usuario en esta aplicación comprometer a otros usuarios, o robar dinero, o realizar algún otro daño permanente y costoso?

Tienes la idea.

El pensamiento adicional es que una contraseña es fundamentalmente una credencial especialmente poderosa que se espera que funcione en cualquier lugar desde cualquier dispositivo en cualquier momento.

Una alternativa al almacenamiento de la contraseña en el dispositivo es generar un token específico del dispositivo a largo plazo, que se guardará en el dispositivo en lugar de la contraseña y se usará para volver a autenticarse solo desde ese dispositivo. Este token no tiene que ser un token de "actualización" de uso único; a veces las aplicaciones contienen la contraseña varias veces y la usan.

Ciertamente, el soporte para cualquier esquema de autenticación adicional requiere complejidad adicional. Las circunstancias pueden ayudar a determinar si vale la pena. En situaciones más sofisticadas, los escenarios de compromiso pueden tener estimaciones de probabilidad y estimaciones de pérdida, junto con los rangos de costos de desarrollo, mantenimiento y soporte, y los métodos de Monte Carlo se pueden usar para ayudar a mejorar la intuición de si los bits de complejidad individuales ofrecen protecciones, al reducir el riesgo y pérdidas, que pueden valer los costos a largo plazo.

¡Buena suerte!

    
respondido por el Jonah Benton 24.06.2018 - 20:04
fuente

Lea otras preguntas en las etiquetas