Troy Hunt destaca algunos puntos excelentes en su artículo: Todo lo que siempre quiso saber sobre la creación de una función de restablecimiento de contraseña segura . Los extractos más relevantes son:
[T] aquí hay dos enfoques comunes:
- Genere una nueva contraseña en el servidor y envíela por correo electrónico
- Enviar por correo electrónico una URL única que facilitará un proceso de reinicio
A pesar de la gran cantidad de orientación en contrario, el primer punto no es realmente dónde queremos estar. El problema al hacer esto es que significa que una contraseña persistente, una con la que puede volver y usar en cualquier momento, ahora se ha enviado a través de un canal inseguro y reside en su bandeja de entrada.
...
Pero hay un gran problema más con el primer enfoque, ya que simplifica el bloqueo malicioso de una cuenta. Si conozco la dirección de correo electrónico de alguien que posee una cuenta en un sitio web, entonces puedo bloquearla cuando quiera, simplemente restableciendo su contraseña; ¡Es un ataque de denegación de servicio servido en bandeja de plata! Esta es la razón por la cual un restablecimiento es algo que solo debería ocurrir después de verificar con éxito el derecho del solicitante a hacerlo.
Cuando hablamos de una URL de restablecimiento, estamos hablando de una dirección de sitio web que es única para esta instancia específica del proceso de restablecimiento.
...
Lo que queremos hacer es crear un token único que se pueda enviar en un correo electrónico como parte de la URL de restablecimiento y luego coincidir con un registro en el servidor junto con la cuenta del usuario, lo que confirma que el propietario de la cuenta de correo electrónico es el que intenta restablecer el contraseña. Por ejemplo, el token puede ser "3ce7854015cd38c862cb9e14a1ae552b" y se almacena en una tabla junto con el ID del usuario que realiza el reinicio y la hora en que se generó el token (más sobre eso en un momento). Cuando se envía el correo electrónico, contiene una URL como "Restablecer /? Id = 3ce7854015cd38c862cb9e14a1ae552b" y cuando el usuario carga esto, la página verifica la existencia del token y, en consecuencia, confirma la identidad del usuario y permite la contraseña para ser cambiado.
...
La otra cosa que queremos hacer con una URL de reinicio es limitar el token en el tiempo para que el proceso de reinicio se complete dentro de una cierta duración, digamos en una hora.
...
Finalmente, queremos asegurarnos de que este sea un proceso único. Una vez que se completa el proceso de restablecimiento, el token debe eliminarse para que la URL de restablecimiento ya no funcione. Al igual que con el punto anterior, esto es para garantizar que un atacante tenga una ventana muy limitada en la que pueda abusar de la URL de restablecimiento. Además, por supuesto, el token ya no es necesario si el proceso de reinicio se ha completado con éxito.
Él hace muchos más puntos buenos sobre cómo evitar fugas de información, CAPTCHA, autenticación de dos factores y, por supuesto, las mejores prácticas básicas como el hash de contraseñas. Creo que es importante tener en cuenta que no estoy de acuerdo con Troy sobre la utilidad de las preguntas de seguridad, prefiriendo el escepticismo de Bruce Schneier sobre la práctica :
El punto de todas estas preguntas es el mismo: una contraseña de respaldo. Si olvida su contraseña, la pregunta secreta puede verificar su identidad para que pueda elegir otra contraseña o hacer que el sitio le envíe por correo electrónico su contraseña actual. Es una gran idea desde la perspectiva del servicio al cliente: es menos probable que un usuario olvide el nombre de su primera mascota que una contraseña aleatoria, pero es terrible para la seguridad. La respuesta a la pregunta secreta es mucho más fácil de adivinar que una buena contraseña, y la información es mucho más pública.