¿Existe alguna inquietud grave al enviar el nombre de usuario y la contraseña del usuario con cada solicitud HTTPS?

7

Debido a ciertos requisitos / restricciones, me pregunto sobre el envío de inicio de sesión y contraseña de usuario con cada solicitud.

Esto de alguna manera no me parece muy bien, aunque creo que para mi caso en particular, podría tener sentido: reduciría la cantidad de solicitudes HTTP, reduciría la latencia y simplificaría el código de interfaz.

Aquí está la situación:

  • El tráfico al servidor proviene de una aplicación móvil
  • Todo el tráfico pasa por HTTPS
  • Mantenemos las credenciales de usuario cifradas en el almacenamiento del dispositivo para iniciar sesión automáticamente en cada inicio de la aplicación
  • El tiempo de espera de la sesión del servidor es muy bajo (pocos minutos) y está fuera de mi control
  • El DB está fuera de mi control; No puedo agregar nada a la base de datos de forma fácil y rápida (sería un gran desafío obtener un campo de base de datos si, por ejemplo, quisiera un token de sesión de larga duración)
  • El tráfico en la aplicación usualmente ocurre en lotes
  • El lote de tráfico típico dentro del tiempo de espera de la sesión es solo unas pocas solicitudes HTTPS
  • Dado que el tráfico proviene de la aplicación móvil, no siempre es posible enviar solicitudes de "mantener la sesión activa"; si el usuario mata una aplicación y la vuelve a iniciar unos minutos más tarde (o se minimiza durante unos minutos), no hay posibilidad de mantener la sesión y debo volver a iniciar sesión en el usuario.

Por lo tanto, el patrón de tráfico típico actualmente es:

#USER OPENS THE APP
POST /autologin    -> response: [ok, here's the new sessionid]|[auth failure, maybe the password changed since]
#SUPPOSING AUTH WAS OK; USER BROWSES AROUND THE APP
POST /someAction1
POST /someAction2
POST /someAction3
#USER IDLE FOR A FEW MINUTES
POST /keepSession
...
#USER MINIMIZES THE APP
#USER RELAUNCHES THE APP, MAYBE SEVERAL MINUTES LATER, MAYBE NEXT DAY
POST /someAction4  -> response: sessionTimeout
POST /autologin    -> response: [ok, here's the new sessionid]|[auth failure, maybe the password changed since]
#SUPPOSING AUTH WAS OK; USER BROWSES AROUND THE APP
POST /someAction4
...

De todos modos, en promedio, tengo que enviar la solicitud de inicio de sesión con bastante frecuencia una vez que la sesión expira; Un porcentaje significativo de solicitudes son solicitudes de inicio de sesión.

Si envío un nombre de usuario y una contraseña en cada solicitud, puedo

  • deshacerse de las solicitudes /autologin en el arranque
  • deshacerse de las solicitudes /keepSession cada pocos minutos mientras el usuario está activo
  • deshacerse de /action - > /autologin - > /action combo en caso de que la sesión haya expirado; bajando de la solicitud 3 a solo 1

Siempre podría enviar tanto la ID de sesión como la Contraseña de inicio de sesión, luego, en el back-end, reutilizar la ID de sesión si todavía es válida, de lo contrario, crear una nueva sesión con el nombre de usuario y la contraseña, y hacer lo que quisiera dentro de la misma llamada HTTP, sin la necesidad para jugar ping-pong entre frontend y backend.

Para resumir, desde mi perspectiva:

Contras:

  • Debería tener cuidado en el backend para no registrar accidentalmente las credenciales de los usuarios en múltiples controladores de solicitudes, no solo uno (controlador de inicio de sesión)
  • podría aumentar el número de solicitudes con inicio de sesión y pasar la carga útil en un factor de N = ~ 4,

Pros:

  • el número total de solicitudes HTTP realizadas por el servidor disminuyó en un 20% +
  • no es necesario que la lógica de frontend mantenga la sesión del usuario; simplemente disparar cada solicitud con credenciales. Si falla debido a un problema de autenticación, cierre la sesión del usuario.

Sabiendo que el tráfico está encriptado con HTTPS, ¿hay algún inconveniente grave en mi enfoque de siempre enviar, iniciar sesión y pasar?

    
pregunta jakub.g 24.09.2015 - 14:53
fuente

3 respuestas

4

A menos que incorpore su propio mecanismo de seguridad (que generalmente no es recomendable), confiará en la seguridad de SSL para proteger la autenticación. Generalmente, esto se hace con algún tipo de token que, si se captura, se puede usar para replicar el inicio de sesión. Por lo tanto, un atacante que puede romper SSL también puede capturar su clave de sesión y hacerse cargo de su sesión existente.

Hay un par de diferencias entre una clave de sesión y un nombre de usuario / contraseña. La primera es que la clave de la sesión terminará por expirar, mientras que un nombre de usuario / contraseña permanecerá durante mucho más tiempo. En general, esto se considera una ventaja de seguridad menor porque un atacante simplemente tiene que ser oportuno en el uso de la clave de sesión capturada. Una diferencia mayor es que la contraseña se puede usar para autenticarse nuevamente cuando se realiza una acción crítica, como transferir dinero en la cuenta o cambiar la contraseña. En este caso, capturar solo la sesión no es útil, ya que el atacante también tendría que capturar la contraseña.

Incluso en un escenario seguro de clave de sesión, el nombre de usuario / contraseña aún se envía una vez por sesión. Si el atacante puede romper completamente la sesión SSL, entonces puede capturar el intercambio de nombre de usuario / contraseña inicial.

Ahora, romper SSL no tiene que significar una ruptura completa. Existen posibles escenarios de interrupciones parciales en las que una ruptura de SSL podría ser más vulnerable a enviar el nombre de usuario / contraseña muchas veces, una vez por sesión.

La conclusión es que usar una clave de sesión es un poco más seguro (si se hace correctamente) que enviar un nombre de usuario / contraseña cada vez. Necesita equilibrar esta seguridad con el resto de sus necesidades de back-end. Pero entiendo que no importa lo que esté haciendo, todavía confía en la seguridad de SSL.

    
respondido por el Steve Sether 24.09.2015 - 18:18
fuente
0

Además de la respuesta de @Steve Sether, la mayoría de los navegadores modernos pueden detectar ataques MITM que se pueden usar para comprometer la clave de la sesión al verificar el (los) certificado (s) del servidor.

Si usa TLS y solo permite certificados válidos, el enfoque descrito no afecta a la seguridad. Además, la clave de sesión y su sesión web son dos cosas diferentes, lo que significa que la vida útil de la clave de sesión es independiente de la sesión de la aplicación web creada entre la aplicación y el servidor.

La clave de sesión garantiza la seguridad en el futuro en el sentido de que comprometer la clave actual no es útil para descifrar sesiones futuras o futuras. Por lo tanto, podría reinicializar la sesión TLS a la velocidad promedio a la que expira la sesión web y enviar el nombre de usuario / contraseña a la mitad de esa tarifa por seguridad.

    
respondido por el Sebi 25.09.2015 - 15:12
fuente
-2

Me suena como una mala idea (la siguiente es solo mi opinión)

Si está enviando el nombre de usuario / contraseña con cada solicitud de HTTP (s), existe la posibilidad de que algunos bits en los datos cifrados no cambien. por lo tanto, asumo que si se capturan suficientes solicitudes HTTPS (en miles o incluso millones), entonces un atacante puede hacerse pasar por un cliente.

Si compara una solicitud HTTP HEAD sin cifrar enviada por un cliente con otra enviada por el mismo Cliente al mismo servidor, no son tan diferentes. por lo tanto, si un atacante puede capturar suficientes de estos en la Secuencia HTTPS, aunque esté cifrado, el atacante aún puede adivinar los otros bits y crear su propio paquete para hacerse pasar por el cliente.

Esta es también una de las razones por las que uno debe expirar las cookies después de un período de tiempo, por lo que es difícil para un atacante recopilar suficientes solicitudes que sean similares.

    
respondido por el JOW 24.09.2015 - 17:32
fuente

Lea otras preguntas en las etiquetas