¿Cómo debería funcionar la autorización de webmail?

3

Estoy creando un cliente de correo web (como gmail). Permite al usuario navegar por los correos electrónicos y enviarlos. Bajo el capó, php usa IMAP y SMTP para hablar con el servidor de correo electrónico.

usuario- > webserver- > mailserver

Cuando el usuario desea usar mi correo web, el servidor web solicita credenciales para el servidor de correo. Cuando el servidor web necesita conectar el servidor de correo, el servidor de correo solicita las credenciales proporcionadas por el usuario.

Así que con este correo web puede conectarse a cualquier servidor de correo que desee. Gmail, yahoo, tu servidor de correo privado, etc. Es como Roundcube, Squirrelmail.

Así que tengo dos niveles de autenticación. En lo que concierne a la parte del servidor web de > hay una sesión implementada. Sin embargo, me siento frustrado por la parte del servidor web y servidor de correo. Estoy usando la función nativa imap_open () de php para conectarse.

  1. Después de que el usuario haya iniciado sesión, puede hacer clic en el botón "actualizar mis correos electrónicos" un par de veces. ¿Está bien si el servidor web envía un nombre de usuario / contraseña CADA VEZ que necesita conectarse al servidor de correo (a través de imap_open)? Dado que dos servidores no tienen tal cosa como una sesión. ¿Hay una mejor manera?

  2. Como el usuario proporciona esta contraseña solo una vez al iniciar sesión, y luego la sesión lo mantiene conectado, necesito una forma de almacenar esta contraseña de manera segura entre las solicitudes que el usuario puede hacer a mi servidor web (haciendo clic en "actualizar mis correos electrónicos" " por ejemplo). Tal vez podría almacenar la contraseña en una cookie cifrada. ¿Hay alguna manera mejor?

pregunta user3702861 10.02.2015 - 19:06
fuente

4 respuestas

4

Para asegurarse de que solo el usuario tenga la clave para su cuenta IMAP, puede guardar las credenciales de inicio de sesión en su sesión de forma simétrica cifrada mediante una clave, que se almacena en una cookie . Por lo tanto, el usuario puede desbloquear las credenciales de inicio de sesión con su cookie, sin que el servidor web no pueda iniciar sesión.

Por supuesto, debe asegurarse de que todas las apariciones de las credenciales se sobrescriban si no se usan más y que otros procesos no las puedan leer.

Si tiene un atacante en el servidor web, es posible que pueda leer los detalles de la sesión, las credenciales cifradas. Si él también puede obtener la cookie al escuchar la conexión, tiene un problema de todos modos.

    
respondido por el sebix 12.02.2015 - 11:19
fuente
3

Dado que el autor menciona que su producto es como Roundcube o Squirelmail ... sé cómo funciona Roundcube.

Bueno, el correo web de Roundcube NO TIENE su propio método para iniciar sesión en los usuarios. Lo que quiero decir es que no hay una base de datos que almacene nada sobre el usuario. Roundcubes toma las credenciales proporcionadas por el usuario y las coloca directamente en imap_open() .

  1. Si establece conexión con el servidor de correo, Roundcube registra al usuario.
  2. Si no establece conexión con el servidor de correo, Roundcube dice "credenciales incorrectas".

Por lo tanto, la contraseña en esta parte: usuario- > servidor web. Es el mismo que en esta parte: servidor web > servidor de correo.

Esto hace que el proceso sea más sencillo. Sin embargo, por lo que sé, la contraseña de texto sin formato o la contraseña cifrada deben almacenarse entre esas solicitudes web, pero no estoy seguro de cómo se hace en Roundcube.

Supongo que podría simplemente almacenarlos en una cookie de sesión (cookie ecnrted como mencionó en su pregunta). Por lo tanto, la contraseña no se guarda en el servidor de ninguna manera, solo vuela entre el servidor y el usuario en cada solicitud web. Dado que está cifrado, no se puede filtrar hasta que no se filtre su clave de cifrado secreta en el servidor.

    
respondido por el user68129 11.02.2015 - 09:24
fuente
1

He estado pensando en esto un poco debido al hecho de que nunca debes almacenar las contraseñas de los usuarios en texto plano. por lo que he encontrado una posible solución para usted.

Cuando un usuario se registre para recibir un nuevo "servicio" en su cuenta (por ejemplo, agrega gmail o yahoo, etc.), lo que tendrá que hacer es:

  1. Pídale nuevamente al usuario la contraseña de su sitio (y valídelo)

  2. Vuelva a descifrar su contraseña con un nuevo salt aleatorio (que debe almacenar) (con un algoritmo hash diferente al que usa para su almacén de contraseña principal) ¡NO ALMACEN ESTO! de ahora en adelante me referiré a esto como KEY_A

  3. genera una clave dsa o rsa con contraseña con KEY_A como la contraseña para el archivo de claves. Se utilizará como clave de acceso para el siguiente paso

  4. Use un método de cifrado seguro (tal vez mcrypt si está en php ya que está integrado) y almacene su contraseña 'encriptada'

  5. Cuando un usuario inicia sesión y se crea una nueva sesión, vuelve a usar su contraseña con el mismo método utilizado en el paso # 2, Cifrala con una clave que se deriva de algo que es único para su sesión pero no se almacena (Digamos que user_agent + session_start_time + su dirección IP + una sal específica del usuario). Almacene este valor encriptado en una cookie http_only, borre dicha cookie al cerrar sesión, obligue a que inicie sesión nuevamente si la cookie no está presente.

Ahora tiene un método para almacenar su gmail / hotmail / etc. credenciales de una manera en la que no tiene una forma directa de saber cómo descifrarlas sin la contraseña que usan para su servicio.

Es muy probable que también sea prudente asegurarse de no almacenar algunos de los componentes utilizados para cifrar la cookie (por lo tanto, al menos deshabilite el registro del agente de usuario en la configuración del servidor web)

Ahora para realizar un inicio de sesión de iMap (o algo similar. simplemente tendría que descifrar la cookie http_only del paso 5 para obtener KEY_A, use KEY_A para desbloquear la clave RSA / DSA, luego use la clave desbloqueada para descifre la contraseña a su servicio, luego realice la transacción iMap, y solo para volver a cero paranoico (en php puede simplemente llamar unset ()) las variables que contienen su contraseña de texto simple, KEY_A, y su tecla rsa / dsa desbloqueada línea de código después de que ya no sean necesarios.

Además de esto, asegúrese de que su servicio DNS también esté configurado de manera segura. (forzar DNS-SEC, tal vez incluso configurar la resolución de DNS de los servidores web a través de una interfaz de red de servicio y no la visible por la web y realizar la resolución del DNS a través de una dirección IP visible "no relacionada" diferente.) Asegúrese de que su https Los certificados están completamente actualizados.

Debido a que enviará de manera efectiva las contraseñas privadas de los usuarios a través de la web, lo último que desea es que alguien inunde la dirección IP de su servidor web con el redireccionamiento de paquetes de resolución de DNS de udp. Se han creado con el propósito de oler las contraseñas.

El único inconveniente de este método (en el que puedo pensar) es que cuando el usuario cambia la contraseña de su servicio, tendrá que volver a ingresarla a todos los demás proveedores de correo electrónico que se hayan registrado. (porque la contraseña cifrada almacenada ya no será válida).

Y por último, pero no menos importante (supongo que esto se hará, pero no tengo forma de estar seguro). ¡elimine el código de depuración ALL relacionado con estas rutinas antes de ponerlo en funcionamiento! p>

La clave completa para esto es garantizar que KEY_A no se pueda derivar de nada que usted almacene (así que no haga un atajo simplemente al volver a marcar el hash de su contraseña, haga el hash de una manera diferente, con un salt diferente).

    
respondido por el Damian Nikodem 11.02.2015 - 01:59
fuente
0

Por qué no almacena las credenciales del servidor de correo como parte de los datos de la sesión del servidor web. Una vez que el usuario escriba su nombre de usuario y contraseña del servidor de correo en su aplicación de cliente de correo web. Usted guarda esta información en el servidor web / sesión de usuario.

Sin embargo, esto significa que cada vez que el usuario inicie sesión en el correo web, deberá autenticar su identidad al menos dos veces, una para el servidor web que aloja al cliente de correo web y otra para el servidor de correo que recibe los correos electrónicos del usuario. Si este es el caso, entonces podría tener un problema de usabilidad. Algunos usuarios se quejarán de la parte en la que deben proporcionar las credenciales para el servidor de correo cada vez que inicien sesión. ¿Por qué no almacena las credenciales del servidor de correo en la misma base de datos donde almacena las credenciales del cliente de correo web?

    
respondido por el Ubaidah 10.02.2015 - 19:32
fuente

Lea otras preguntas en las etiquetas