Actualmente tengo la siguiente configuración para el manejo de usuarios que olvidaron su contraseña.
- Un usuario escribe su dirección de correo electrónico y presiona el botón de contraseña olvidada.
-
Busco el usuario que pertenece a esa dirección de correo electrónico y almaceno una nueva 'solicitud de contraseña olvidada' en la base de datos. El elemento de solicitud de contraseña olvidada tiene este aspecto:
Guid ForgotPasswordRequestId; Guid UserId; DateTime ValidUntil;
-
Genero un token para identificar la solicitud de contraseña olvidada al convertir el ForgotPasswordRequest Guid en una cadena Base64. El Guid es un Guid versión 4 (aleatorio, no basado en el tiempo o en la dirección MAC). Consulte este enlace de MSDN para obtener información sobre la implementación.
-
Creo un enlace como
www.example.com/account/ForgotPassword?token=TOKEN
que se envía al usuario en un correo electrónico. -
Cuando alguien visita ese enlace dentro de las 24 horas, puede establecer una nueva contraseña para esa cuenta.
Creo que las posibilidades de que alguien adivine el token son pequeñas, ya que un Guid es un número de 122 bits (128 bits, menos 6 bits para la información de versión). Por lo tanto, un pirata informático debería intentar, en promedio, (2^122 / 2)
tokens dentro de las 24 horas antes de tener éxito. Si mis cálculos son correctos, es 3 * 10^31
tokens por segundo, lo que estoy seguro de que mi servidor no puede manejar;). Además, el token que deben adivinar no está relacionado de ninguna manera con el usuario para el que desea restablecer la contraseña.
Sin embargo, ¿es correcto generar el token directamente desde un Guid generado? ¿Hay alguna forma de que usar un Guid y no un generador seguro de números aleatorios haga posible un ataque? ¿Hay algún otro problema en este esquema que lo haga inseguro?
He visto esta pregunta , aunque su relación no explica las mejores prácticas para generar el token.