¿Este esquema de sesión no basado en cookies es horriblemente vulnerable a algún ataque?

4

Estoy trabajando en una aplicación web grande que se ejecuta completamente dentro de una sola página web. Por diversas razones, no queremos utilizar cookies en esta aplicación web, pero es necesario hacer un seguimiento de si un usuario ha iniciado sesión o no. Todas nuestras conexiones son sobre SSL. Aquí es cómo planeamos realizar un seguimiento de las sesiones:

Con cada respuesta enviada por el servidor, envía un token de sesión.

El token de sesión es una cadena cifrada que contiene lo siguiente:

  • El ID de usuario
  • A SessionID
  • Una sal (generada aleatoriamente cada vez)
  • Una marca de tiempo actual
  • Una marca de tiempo de caducidad, exactamente media hora después de la marca de tiempo actual

Cuando el cliente envía una solicitud, también debe enviar este token de sesión. El token se descifra y las marcas de tiempo se verifican para ver si están separadas por media hora, y que la hora actual está entre las dos marcas de tiempo. Si es así, la solicitud se procesa, utilizando el ID de usuario para identificar quién realizó la solicitud. De lo contrario, la solicitud no se procesa y se envía una respuesta que indica al cliente que cierre la sesión del usuario.

¿Este sistema nos dejará horriblemente vulnerables a las personas que se identifican falsamente como usuarios? ¿Ves algún otro problema con esto?

    
pregunta Adams Tower 11.01.2012 - 18:46
fuente

4 respuestas

4

Básicamente, está tratando de almacenar información de la sesión del lado del cliente, no de permanentemente , pero de todos modos almacena. Esto se puede hacer, pero es delicado.

El modelo básico es el siguiente:

  • Un cliente autenticado recibe un valor generado aleatoriamente, por ejemplo, un "ID de sesión". Algo tan grande que intentar valores aleatorios tendría una probabilidad insignificante de alcanzar un ID de sesión existente, por lo que no es posible "robar" una sesión. (16 bytes aleatorios son suficientes, si usas un PRNG fuerte).

  • El ID de sesión se envía al cliente, y el cliente lo envía para cada solicitud.

  • El servidor mantiene datos específicos del cliente en una base de datos (o mapa en memoria) indexado por el ID de sesión, incluyendo cosas como la fecha y hora de la última solicitud del cliente.

Desde este modelo, es posible descargar algunos de los requisitos de almacenamiento en el cliente. Esto es lo que sugiere: con el ID de sesión, envía algunos otros datos al cliente, como un blob opaco que el cliente debe enviar sin cambios con su siguiente solicitud . Permítanme resaltar los puntos importantes:

  • "datos al cliente" : estos datos estarán disponibles para el cliente; Esto puede o no ser un problema, dependiendo de los datos exactos. No hay ningún problema en dejar que el usuario aprenda su propio nombre o la fecha de su última solicitud, ya que podría haberlo adivinado solo. Sin embargo, en general, la herramienta para eso es cifrado simétrico , con una clave simétrica que el servidor eligió al azar , y nunca se divulga a ningún cliente. Tenga en cuenta que esto puede generar problemas en los servidores de varias aplicaciones y en los servidores que se reinician (según el modelo de equilibrio de carga, es posible que tenga que compartir la clave entre las aplicaciones).

  • "se supone que el cliente debe devolver" : ¿qué sucede si el cliente, por un capricho, decide no enviarlo? O, en lugar de un capricho, ¿la conexión del cliente muere? (Se producen cortes de energía no ). Si el servidor mantiene las estructuras en la memoria indexadas por el ID de la sesión, entonces necesita algún tipo de limpieza automática en el tiempo de espera. Luego, más o menos tendrá que "cerrar sesión" a la fuerza a los clientes inactivos, o hacer que envíen una solicitud ficticia con regularidad.

  • "sin cambios" : el cliente puede intentar alterar su blob, por ejemplo. cambiar la parte de "nombre de usuario". Contrariamente a lo que parece suponer, el cifrado no no protege contra alteraciones. Algunos tipos de cifrado pueden hacer que la tarea sea un poco incómoda o borrosa para el atacante, pero el cifrado no fue para eso y no obtendrá un nivel adecuado de protección de esa manera. Lo que desea es un Código de autenticación de mensajes , que se puede ver como una especie de "suma de comprobación con clave". Un MAC le permitirá detectar, en el servidor, una alteración no deseada, a menos que la "alteración" se trate de reemplazar el blob por completo con otro blob completo también enviado por el servidor, al mismo u otro usuario.

    Un MAC necesita el mismo tipo de clave que el cifrado simétrico, por lo que plantea los mismos problemas sobre la administración de claves. Además, si desea tener un MAC y para cifrar, tendrá la tentación de utilizar la misma clave para ambos usos. Esta no es una buena idea Si desea encriptar y tener un MAC, debe usar un modo dedicado como EAX , para el cual las personas inteligentes tienen ya descubrí y desactivé los escollos inherentes a tal esfuerzo; o, podría intentar hacer una construcción casera, y permitir que su sistema se una a la horda de sistemas caseros que no fueron tan seguros como su diseñador inicialmente soñaba.

  • "su próxima solicitud" : el cliente puede enviar blobs fuera de orden, duplicando un valor de blob más antiguo, posiblemente mezclando blobs de dos conexiones paralelas. Varios problemas pueden surgir de tales juegos. El blob representa la memoria de su servidor: se trata de datos que confía al cliente porque el servidor no desea recordarlo; en consecuencia, nada impide que el cliente haga que el servidor lo "olvide" o "rebobine" la memoria del servidor. Ni el MAC ni el cifrado pueden arreglar eso. Dependiendo de su aplicación, esto puede o no ser un problema, pero es probable que lo sea.

Finalmente, la descarga de datos al cliente significa que está cambiando el ancho de banda de la red por el tamaño de la RAM: ahorra algunos bytes de RAM, pero tiene más datos para enviar y recibir. En términos económicos, no estoy seguro de que este sea un movimiento inteligente.

    
respondido por el Tom Leek 11.01.2012 - 21:21
fuente
4

KISS - Keep It Simple, S_ _ _ (completa lo que quieras).

Pase solo un ID de sesión al cliente. Verifique esa ID de sesión en el lado del servidor. El servidor debe asignar a quién pertenece el ID de sesión. El servidor debe ser responsable de que caduque esa ID de sesión.

Bajo su sistema actual, no está claro si un usuario puede cambiar su identidad cambiando el nombre de usuario. Tampoco está claro qué sucederá si alteran las marcas de tiempo.

    
respondido por el Jeff Ferland 11.01.2012 - 19:42
fuente
2

La respuesta de Althoug Tom Leek ya ha sido aceptada, hay un par de puntos que no aborda.

Como se describe

  1. aquí no hay nada que evitar contra las repeticiones de terceros y XSRF
  2. el identificador de sesión se puede marcar / transferir fácilmente
  3. requerirá una gran cantidad de código personalizado (más código = más errores = menos seguro) para administrar la sesión
  4. para las cookies, puede restringir fácilmente que un ID de sesión no sea accesible a javascript y / o solo se use para SSL y / o restringir a una ruta específica, así que a menos que agregue mucho código, la superficie de ataque es mucho más grande
  5. requerirá una gran cantidad de código para completar todos los métodos posibles de navegación entre páginas: el mecanismo de administración de sesión de PHP proporciona un mecanismo para propagar una identificación de sesión a través de las variables GET CGI, pero nadie lo usa porque tiene problemas con javascript, formularios POST , redirección .... además de los otros problemas descritos anteriormente.

Si va por el camino de usar un valor del lado del cliente para hacer referencia a los datos del lado del servidor, entonces no use (a) cifrado simétrico para generar el identificador, si su secreto está comprometido, todo su sistema está comprometido. Utilice un valor aleatorio y mantenga una tabla de búsqueda al lado del servidor. (Esto se aplica independientemente de donde almacene el ID de sesión).

Solo ni siquiera pienses en intentar esto

    
respondido por el symcbean 13.01.2012 - 14:37
fuente
0
  

El token de sesión es una cadena cifrada ...

Mientras esté usando un buen, aleatorio, privado (= no es parte de los datos transmitidos), sal y actualice (recodifique) la cadena cifrada con más frecuencia (para evitar "repeticiones" ), podría hacerse.

Pero desde el punto de vista de la seguridad, me está pasando escalofríos por la espalda hasta pensar que alguien lo está implementando de esa manera. Estás mostrando los datos mundiales que podrías y deberías proteger.

En otras palabras: ¡no lo hagas así!

Permítanme hacer tres preguntas simples:

  1. Dado que potencialmente estás mostrando los datos cifrados a todos en público, ¿qué tan seguros están tus datos cifrados que, cuando se trata de ingeniería inversa, tu implementación de criptografía?
  2. ¿Qué pasa con los ataques de fuerza bruta y cómo planea defenderse de ellos ya que su sistema no puede saber si los datos pasados se han desordenado (ejemplo: un token recodificado que contiene diferentes ¿Datos como otro IP)?
  3. ¿Sabe que, al proporcionarle la sal con los datos cifrados, en realidad está proporcionando parte de la clave necesaria para decodificar los datos que está transmitiendo?

Por lo tanto, una de las razones más importantes para no hacer lo que haces es que no puedes verificar la validez de los datos de tu token o los datos encriptados contenidos.

Además, proporcionar la sal que está utilizando junto con sus datos encriptados es un absoluto "no-no" porque dicha sal debe mantenerse absolutamente privada. Es "parte de la mezcla" lo que en realidad debería dificultar la fuerza bruta. ¡Publicar la sal con los datos cifrados anula el propósito de la sal y lo hace tan fácil como si no hubiera sal!

Al final, siempre debe recordar el hecho de que los procedimientos criptográficos y / o de seguridad implementados de manera deficiente o incorrecta no podrán protegerlo como se esperaba . Por lo que he leído en la descripción que acompaña a tu pregunta, lamento decir que lo estás haciendo mal en varias áreas.

    
respondido por el user6373 11.01.2012 - 22:43
fuente

Lea otras preguntas en las etiquetas