¿Es seguro mi sistema de autenticación sin contraseña (enlace mágico OTPW)? [duplicar]

3

He implementado un sistema de autenticación sin contraseña (donde los usuarios solo inician sesión con un "enlace mágico" enviado a su correo electrónico) por mi cuenta. Sé que diseñar sistemas de seguridad sin experiencia es realmente malo, así que pregunto si mi sistema tiene algún agujero obvio. Así es como funciona:

  1. El usuario escribe su correo electrónico & un nombre de usuario único en el cliente JS (SPA)
  2. El correo electrónico & el nombre de usuario se envía a mi servidor API (en GET / cadena de consulta)
  3. El servidor de API consulta la Base de datos de usuarios (consulte a continuación el diseño de esta base de datos) para ver si el correo electrónico ya existe
  4. Si no es así, el correo electrónico se agrega a la base de datos de usuarios junto con el nombre de usuario (nuevo usuario)
  5. Si lo hace, el servidor API garantiza que el nombre de usuario coincida con el correo electrónico, de lo contrario responde con un error
  6. El servidor API genera un GUID de alta entropía (cadena larga y aleatoria) y lo almacena en la base de datos de usuarios (en la misma fila que el correo electrónico y el nombre de usuario)
  7. El servidor API envía al usuario un correo electrónico con un enlace que contiene el GUID en una cadena de consulta a una ruta especial '/ auth /'
  8. El servidor API almacena la hora exacta en que se envió este correo electrónico en la base de datos de usuarios
  9. Si el enlace no se presionó dentro de los 30 minutos posteriores a ese tiempo, el GUID se eliminará de la Base de datos de usuarios (para que el usuario tenga que iniciar sesión nuevamente)
  10. Si se presionó el enlace dentro del tiempo, el servidor API genera un nuevo GUID de sesión, lo almacena en la base de datos de usuarios & pone en una cookie que se intercambia en todas las próximas solicitudes (es decir, cada vez que se produce una nueva solicitud, el servidor API se asegura de que el GUID de sesión coincida con el de la base de datos de usuarios, lo que indica que están conectados)
  11. El GUID de la sesión se elimina de la base de datos de usuarios si el usuario decide cerrar sesión
  12. El GUID de la sesión también se elimina cada 3 días (por lo que los usuarios tienen que iniciar sesión cada 3 días)

La base de datos de usuarios tiene las siguientes columnas, con username como clave principal:

| username | email | magic_link_guid | magic_link_guid_date | session_guid | session_guid_date |

Algunos problemas que no sé cómo solucionar:

  1. Se realiza una llamada a la base de datos para cada solicitud, que no puede ser buena
  2. El manejo de los roles de usuario sería realmente difícil con este método
  3. Esto parece susceptible a los ataques XSS / CRSF

Una vez más, sé que implementar mi propio sistema es malo, pero no puedo encontrar un sistema sin contraseña ya hecho para .NET / C # :(.

    
pregunta Biarity 18.12.2016 - 07:20
fuente

1 respuesta

2

Lo que describe es un sistema de autenticación token . No es tan malo, y como se ha dicho en los comentarios, es una forma común de implementar una función de contraseña olvidada .

Algunas aplicaciones bien conocidas, como redmine , ofrecen este sistema de autenticación de forma nativa para facilitar la implementación de las operaciones automáticas utilizando una API.

Un problema es la duración del token, lo que usted llama el GUID de sesión . Aquí obliga al usuario a conectarse al menos cada tres días, lo que es realmente intensivo. Si es por motivos profesionales, generalmente se les permite a los empleados tomarse vacaciones por más de 3 días, y para tareas no profesionales, hacerlos cada 3 días es enthusiam (de la insignia de plata en la red SE para visitar un sitio durante 30 días consecutivos). ¿Qué es un usuario que va por una pista en montaña sin acceso a la red? Eso significa que tendrá que usar de forma intensiva la generación de contraseñas que solo se basa en el nombre de usuario y el correo electrónico, lo cual no es lo suficientemente seguro para un uso generalizado. Pero también sabe que cuanto más tiempo se use el GUID de sesión, mayor será el riesgo de robo.

Otra debilidad es el manejo de un lado del cliente de cookies permanentes para almacenar el token. Eso es más o menos almacenar una contraseña en texto claro en el cliente que se sabe que es mala. Esto solo debería asustar a cualquier usuario consciente de la seguridad. Por ejemplo, en Redmine, el token se genera y almacena en la aplicación, y el usuario genera uno justo antes de usarlo para sus solicitudes de API.

Ahora para tus preguntas:

  • Se realiza una llamada a la base de datos para cada solicitud, que no puede ser buena

    No hay problema aquí. Los cachés son para mitigar ese problema. Ni siquiera intente hacerlo a mano, solo confíe en un caché conocido. Además, al hablar del lado del cliente del navegador, solo puede confiar en las sesiones HTTP (o HTTPS) una vez que el usuario esté autenticado

  • El manejo de roles de usuario sería realmente difícil con este método

    Los roles de usuario no se manejarán del lado del cliente. Debería tener una tabla que describa los roles permitidos a un usuario: User_ID | Role_ID . Cuando encuentra un usuario, busca sus roles y los guarda del lado del servidor en la sesión. O confíe en el caché si utiliza una API no conectada.

  • Esto parece susceptible a los ataques XSS / CRSF

    Puede o no ser un problema. ¡Pero al menos debe asegurarse de que la cookie de token esté asociada solo con su propio dominio! Y también confiar en formas de mitigación comunes en los formularios.

TL / DR: este es un sistema de autenticación de token. Puede utilizarse como complemento de un sistema de autenticación principal, pero tiene serias deficiencias en las implementaciones descritas si se usa solo. Por el contrario, las preguntas restantes no son realmente un problema y se pueden responder de la manera habitual.

    
respondido por el Serge Ballesta 18.12.2016 - 10:48
fuente