¿Existen alternativas seguras a los enlaces de restablecimiento de contraseña de un solo uso?

27

Actualmente tenemos lo que creo que es un esquema bastante estándar para tratar con restablecimientos de contraseñas. Nuestros enlaces de restablecimiento son enlaces de un solo uso: caducan inmediatamente después de haberlos visitado, incluso si el usuario no restablece su contraseña.

Sin embargo, nuestros clientes son predominantemente (99%) empresas con un filtro de spam agresivo. En particular, algunos de nuestros principales clientes (distritos escolares) tienen filtros de correo no deseado que realizan el escaneo de enlaces. Visitan [hasta N] enlaces en un correo electrónico como parte de sus algoritmos. Cuando los usuarios solicitan un restablecimiento de la contraseña, la visita del filtro de correo no deseado "caduca" antes de que el usuario los vea.

¿Existen alternativas al enlace de un solo uso que sean igualmente seguras? ¿O son lo suficientemente seguros como para que caigan dentro del ámbito de las prácticas aceptables?

También tenemos que considerar la usabilidad. Nuestros clientes generalmente son tan poco técnicos como usted puede obtener. Así que, idealmente, el procedimiento de restablecimiento de la contraseña no será mucho más complicado para el usuario.

Esto es lo que hemos pensado hasta ahora:

  • Almacene el token de restablecimiento en la sesión. El enlace permanecerá activo mientras la sesión original del navegador esté abierta o la contraseña no haya sido realmente restablecida. Puede complicar el proceso para los usuarios que usan dos dispositivos diferentes para su correo electrónico y navegación (por ejemplo, correo electrónico en el teléfono + computadora portátil para la navegación).
  • Caduca el enlace después de N minutos. Creo que he visto esto. Pero, no sé qué límite de tiempo es un equilibrio aceptable entre utilizable y seguro.
  • Vence el enlace solo después de que se haya enviado el formulario. Algunos usuarios pueden visitar el enlace, ponerlo en el historial del navegador, pero nunca enviar el formulario. ¿Es ese un nivel de riesgo aceptable?
pregunta svidgen 25.08.2014 - 16:50
fuente

6 respuestas

15

Como siempre, debe considerar el valor del activo que intenta proteger para evaluar adecuadamente si un procedimiento de seguridad es adecuado o no. Normalmente, estará dispuesto a aceptar una menor facilidad de uso cuando el valor de su activo sea alto.

Esto significa que es imposible para usted que usted mismo estimar si una solución dada es suficientemente suficiente .

Dicho esto, una forma sencilla de resolver su problema es no hacer que sus enlaces caduquen inmediatamente, sino que caduquen después de un período de tiempo O cuando se haya restablecido la contraseña (lo que ocurra primero).

Para decidir si esto es lo suficientemente seguro para usted, y suponiendo que está satisfecho con la configuración actual, deberá tener en cuenta los siguientes cambios:

El mismo enlace ahora se puede reutilizar varias veces. Esto podría debilitar la seguridad del sistema.

Sin embargo, actualmente está trabajando en un supuesto que es incorrecto: la primera persona que visita un enlace es el usuario legítimo. Claramente no es el caso (como has notado). La consecuencia es que realmente no aumenta la seguridad general al hacer que el enlace caduque inmediatamente después del primer acceso.

Por lo tanto, en mi opinión , cambiar la forma en que expira su token de acceso parece una solución mejor: aumenta la facilidad de uso sin afectar la seguridad general del sistema.

Sin embargo, podría considerar la posibilidad de incluir una validación de segundo nivel en la página en la que llega al usar su enlace de restablecimiento. Algo que de alguna manera mejorará su confianza en la identidad del usuario (por lo general, se usa una "pregunta de seguridad" aunque ese modelo no es muy bueno).

    
respondido por el Stephane 25.08.2014 - 17:13
fuente
8

No veo la seguridad de un enlace de restablecimiento de contraseña de un solo uso como lo describe usted. La mayoría de los enlaces de un solo uso no son válidos si se cambia la contraseña, no si la página se carga por primera vez. ¿Una pulsación accidental en recargar o F5 hará que la solicitud no sea válida? Este es un tipo de experiencia de usuario muy mala.

Pensemos en esto: un usuario pide un enlace de contraseña, pueden suceder dos cosas:

  1. Un 'hacker' recibe el correo primero. Al usar su sistema, el usuario real no tiene oportunidad de abrir este enlace, esto es muy malo para usted y para el usuario. Pero en este caso, no hay seguridad adicional al dejar que el enlace caduque la primera vez que se use.
  2. El usuario recibe el correo como lo desea. Todo está bien aquí, pero si se realiza una actualización accidental, el usuario debe comenzar con el pedido de un nuevo enlace.

Para hacer que el sistema sea más seguro, puede crear un sistema donde se envíe un correo adicional al usuario con un enlace para "recuperar" la contraseña anterior, si él / ella no fue quien la cambió. No quiero que envíe la contraseña antigua en texto simple al usuario (ni siquiera debería poder hacerlo). Lo que quiero decir es historizar el hash y el salt de la contraseña anterior y, si el usuario hace clic en "revertir", solo tiene que utilizar el hash y la contraseña antiguos nuevamente. Seguramente, esto no ayudará si la cuenta principal está comprometida, pero para su ejemplo con una computadora pública donde se almacena el enlace de restablecimiento, sería útil.

Además, podría prohibir cambiar el correo de las cuentas los primeros X días después de cambiar la contraseña. De esa manera, un Hacker no podría bloquear al usuario completamente (siempre que la cuenta de correo no esté comprometida, pero en este caso hay muy poco que puedas hacer).

Otra opción es darle al usuario un código después de registrarse (por carta a la antigua para una mejor seguridad, si esto es demasiado costoso, muéstrelo en la propia página cuando el usuario inicie sesión por primera vez con la solicitud expresa de imprimir fuera (aún mejor que enviarlo a la posible cuenta de correo comprometida) que actúa como una recuperación de emergencia para la cuenta dada. Por ejemplo, cuando se ingresa este código, el usuario puede ingresar un nuevo correo y contraseña para obtener acceso a la cuenta, sin importar lo que pase. Pero este código tiene que ser muy seguro, y en realidad no debe guardarse en ninguna computadora.

Se agregaría aún más seguridad mediante la autenticación de dos factores, como puede usar con Google, GitHub y muchos más. Incluso puede usar el sistema desde Google , por lo que no tiene que crear todo usted mismo. De esta manera, un atacante tiene que robar el teléfono celular del usuario, lo que hace que los ataques aleatorios sean imposibles.

Y, por último, un punto muy importante e importante: NUNCA envíe la contraseña por correo. ¡He visto muchos sitios web grandes que hacen esto y no hay forma de que esto sea una buena idea!

    
respondido por el Tokk 25.08.2014 - 17:10
fuente
2

La amenaza real es que una cuenta podría ser secuestrada . Actualmente su seguridad está basada en mantener en secreto los enlaces de restablecimiento de contraseña , porque con ello cualquiera puede establecer una nueva contraseña a voluntad. El uso de un enlace de un solo uso no ayuda porque no sabe si el primer visitante es el usuario real o un impostor.

Para mejorar su situación, hay tres opciones

  • Mantenga el enlace de restablecimiento de contraseña en secreto utilizando un medio seguro en lugar de correos electrónicos sin cifrar . Por ejemplo, correo electrónico encriptado PGP, SMS (no encriptado pero más difícil de interceptar), mensaje de texto seguro, carta en papel, ...
  • No confíes en que el enlace sea secreto . Entonces necesitas otra forma de autenticar al usuario. Todos los ejemplos que puedo imaginar son costosos: una contraseña más compleja que fue enviada por servicios postales (como un PUK), que envía un fax con información personal (también podría ser falsificada, pero es más difícil), preguntas adicionales que solo el usuario podría responder ...
  • Mantenga su solución actual, permita múltiples visitas a la página de restablecimiento de contraseña, rechace los intentos después de un período de tiempo definido (por ejemplo, 2 horas) y espere que su red esté segura. (Anécdota: Hasta 2013, la mayoría de los proveedores de correo electrónico de Alemania intercambiaron correos electrónicos sin cifrar).
respondido por el Christian Strempfer 26.08.2014 - 13:18
fuente
1

Un enfoque de este problema, que estoy considerando implementar, podría funcionar de la siguiente manera:

  1. El usuario abre la página de restablecimiento de contraseña, que tiene un formulario con un campo de dirección de correo electrónico.
  2. El usuario POSTE el formulario con su dirección de correo electrónico
  3. El servidor envía una contraseña de un solo uso a la dirección de correo electrónico ingresada por el usuario.
  4. La respuesta del servidor a la solicitud POST con un nuevo formulario que contiene:
    • Campo oculto con un valor secreto
    • Campo de texto para ingresar la contraseña de un solo uso
    • Dos campos de contraseña para ingresar la nueva contraseña
  5. Al enviar el segundo formulario, el servidor verifica que el valor secreto en el formulario y la contraseña de un solo ingreso que se ingresan de hecho se correspondan entre sí. Además, verifica que los valores no tengan más de x horas (para algunas x entre 1 y 24).
  6. Si todo se ingresó correctamente, la contraseña se restablece.

Esto es similar a usar una cookie de sesión, pero es probable que el valor secreto en un campo de formulario sea menos persistente que una cookie de sesión. Es posible combinar de tal manera que la primera solicitud POST cree tres valores, uno en el correo electrónico y dos en el campo de formulario y cookie en la respuesta POST, y la segunda solicitud POST debe contener los tres valores para restablecer la contraseña.

Una variación de este enfoque, que también estoy considerando es la siguiente:

  1. El usuario abre la página de restablecimiento de contraseña, que les informa sobre una dirección de correo electrónico única en el mismo dominio que la página web (o un subdominio). Además, la página contiene un formulario con un campo oculto con un valor secreto y un campo de contraseña de un solo uso.
  2. El usuario envía un correo electrónico a la dirección de la que se les informó.
  3. Al final de DATA , el servidor de correo receptor inmediatamente comienza a enviar una respuesta a la dirección de correo electrónico del usuario. Esta respuesta contendrá una contraseña de un solo uso.
  4. La contraseña de un solo uso que se envió al usuario ahora se copia del correo electrónico al formulario.
  5. El servidor verifica que el campo oculto y la contraseña de un solo uso se correspondan entre sí (conectados a través de la única dirección de correo electrónico).
  6. Si tiene éxito, al usuario se le presentan las cuentas de usuario registradas en la dirección de correo electrónico verificada.

Es posible que el segundo enfoque aún no esté completamente pensado, pero me imagino que tiene las siguientes ventajas en lugar de simplemente enviar un correo electrónico al usuario:

  • Tiene una oportunidad más para validar que el usuario sí controla la dirección de correo electrónico, ya que puede validar los registros SPF en este momento.
  • Es menos probable que moleste a los usuarios con correos electrónicos de restablecimiento de contraseña ilegítimos, ya que un atacante tendría que pasar la verificación SPF antes de que se envíe el correo de restablecimiento.
  • Es menos probable que el correo de restablecimiento esté bloqueado por un filtro de correo no deseado, porque es una respuesta real a un correo electrónico enviado por el usuario.
respondido por el kasperd 26.08.2014 - 16:59
fuente
0

El sistema de correo con el que está tratando tiene una gran violación de seguridad por sí misma. Un robot que lee correos seguros no es un problema, pero un robot que envía partes de mensajes supuestamente seguros (enlaces) a Internet es simplemente inaceptable. Por triste que sea, descarta los enlaces como medios seguros para transportar datos de los usuarios al servidor. Debe considerar otras opciones, sin enlaces personalizados en absoluto:

1) Reemplace los enlaces que llevan datos en la URL con un enlace genérico a un código de seguridad de formulario + copiable. Sin duda, es una experiencia de usuario peor, sin embargo, si despeja el correo y la forma al mínimo y proporciona instrucciones breves y claras, debería ser manejable para todos.

2) Utilice contraseñas de un solo uso en su lugar. El correo contendría una contraseña única e instrucciones para iniciar sesión con él, lo que redirigiría al usuario a la página "definir una nueva contraseña".

Recomiendo el segundo enfoque, ya que es menos amenazador para los usuarios (ya están familiarizados con el procedimiento de inicio de sesión y puede ocultar todo el proceso para que parezca similar al inicio de sesión), no es necesario mantener otra página (la "entrada" reinicie el código "página), y el mensaje es corto y compacto (" su nueva contraseña: ") para que pueda usar otros medios de entrega, como mensajes de texto.

    
respondido por el Agent_L 26.08.2014 - 10:32
fuente
0

Deberías considerar usar dos métodos simultáneamente:

  1. Caduca el enlace después de N minutos / horas

  2. Vence el enlace solo después de enviar el formulario.

Esto debería ser un buen compromiso entre la seguridad y la facilidad de uso.

    
respondido por el michal 26.08.2014 - 16:02
fuente

Lea otras preguntas en las etiquetas