¿Cómo asegurar los valores de las sesiones de almacenamiento en webapps?

2

EDITAR: Cambié el título de esta publicación de "¿Cómo administrar sesiones en aplicaciones web?" a "¿Cómo asegurar los valores de las sesiones de la tienda en webapps?" como podría haber sido engañoso

En los últimos meses encontré escenarios interesantes que me hicieron preguntarme cómo administrar las sesiones de aplicaciones web.

Hace algunos meses leí sobre un Inyección de SQL en Joomla 3.4 que permitiría a un atacante realizar un secuestro de sesión. Esto es posible porque Joomla 3.4 almacena en la base de datos el valor de la sesión de cada usuario que se conecta a Joomla. Lo que es interesante es que hace un par de semanas realicé un poco en el dominio de un amigo que él hizo hace mucho tiempo. Su sitio web es tan antiguo que todavía está usando Joomla 1.1. Inmediatamente pude encontrar una inyección SQL en uno de los complementos que instaló, así que recordé la tabla de sesiones y busqué eso. Lo encontré y traté de mostrarle el efecto de la vulnerabilidad. La cosa es que ... no pude. Los valores almacenados en la base de datos son diferentes de los que recibe el navegador. Revisé el código fuente de Joomla y resulta que Joomla 1.1 genera un número pseudoaleatorio, realiza algunas operaciones md5 con ese número, y envía al navegador el número pseudoaleatorio y almacena en la base de datos el resultado de las operaciones md5. De esta manera, simplemente no pude realizar un secuestro de sesión en absoluto.

También intenté informar a la comunidad de Joomla sobre esto, pero no lo hacen. Parece que se preocupa por eso. A mí me parece muy importante, un software de 10 años no permitiría a un atacante realizar un secuestro de sesión en caso de que se encuentre una inyección SQL mientras que la nueva versión lo haría.

Comencé a preguntarme cuál sería la mejor manera de administrar los valores de las sesiones. ¿Por qué almacenarlos en la base de datos? ¿Por qué no usar simplemente lo que proporciona el lenguaje de programación de back-end (como session_start en php)?

¿Qué piensas al respecto?

    
pregunta Federico 07.09.2016 - 14:52
fuente

2 respuestas

3

Sí, es una práctica recomendada para hash tokens de sesión dentro de la base de datos. De esta manera, las sesiones no pueden ser secuestradas si los datos están expuestos. Los tokens de sesión deben ser generados con al menos 64 bits de entropía .

Por lo tanto, el valor proporcionado dentro de cookie = token, el valor almacenado en la base de datos = token hashed.

A partir de 2016, se recomienda SHA-2 para crear el hash. Tenga en cuenta que las sales no son necesarias para los valores generados utilizando suficiente entropía.

A menudo se requiere un servidor de base de datos para el almacenamiento de sesiones del lado del servidor donde los servidores están agrupados (aunque en su lugar se puede usar una capa de almacenamiento en caché). Aunque puede usar controladores personalizados de PHP para hacer esto, parece que los autores de Joomla decidieron para rodar los suyos, que son vulnerables a los ataques de extracción de datos que mencionas.

También es una buena práctica restringir el acceso al mecanismo de almacenamiento. Por ejemplo, una cuenta de base de datos con acceso de escritura a la tabla se puede utilizar para iniciar sesión y cerrar sesión y actualizar la caducidad de la sesión, y una cuenta de base de datos para acceso de lectura para verificar la sesión de inicio de sesión. El resto de la aplicación podría usar una cuenta de base de datos que no pueda acceder a la tabla de sesiones. Se podría utilizar una "pimienta" / "sal de todo el sistema" secreta para mitigar otros ataques en los que se podría escribir la tabla de la sesión.

    
respondido por el SilverlightFox 08.09.2016 - 12:58
fuente
0

No.

Hay mucho juego de manos en el código que nos has mostrado, pero no hay magia de seguridad real.

Generando IDs

Si inicio sesión en el sitio web de mi banco y obtengo una cookie de sesión con valor 435812, no necesito ser un hacker especialmente 733T para pensar que puedo ver algo interesante si cambio esto a 435811, 435810, ...

Los

ID de sesión deben ser impredecibles, pero al mismo tiempo únicos . Usar un hash criptográfico es una buena manera de crear un conjunto de valores aleatorios y dispersos. Casualmente, la mayoría de las implementaciones generan un valor que se puede trasladar a diferentes representaciones (piense en urlencode, htmlentities, mysqli_real_escape_string, etc.) sin escape adicional.

Recuperando la sesión El punto principal de los datos de la sesión es que la información almacenada en el servidor se puede recuperar en una fecha posterior. Eso significa que las solicitudes posteriores de un usuario deben asignarse al mismo conjunto de datos. A partir del código que nos ha mostrado, Joomla 1.1 parece hacer esto al mantener una tabla de búsqueda que asigna el valor de la cookie al identificador de la sesión. Si puede inyectar SQL, entonces probablemente pueda inyectar SQL con una combinación o sub consulta.

Modelado de amenazas Lo que es aún peor que la falta de protección que proporciona, es que hace que la enumeración de las sesiones sea aún más fácil, ya que se puede acceder a una lista de las sesiones disponibles en la base de datos.

Pero el blackhat de inyección de SQL es solo un modelo de amenaza. La inyección de código también es un riesgo (especialmente en CMS sin mantenimiento, como Joomla. Poner el ID de sesión directamente en la cookie de sesión y usar un controlador basado en archivos es tan vulnerable si el atacante puede inyectar código PHP en el sistema.

Luego existe la posibilidad de atacar el almacenamiento directamente, ya sea en su lugar o desde una copia de seguridad para descubrir qué datos hay en la sesión.

la mejor manera de administrar los valores de las sesiones

Almacenarlos en una base de datos es el segundo denominador común más bajo después de almacenarlos usando el controlador predeterminado en el sistema de archivos. Simplifica la separación de datos de sesión entre vhosts en hosts compartidos (aunque no mucho). También es fácil de escalar a múltiples dispositivos que sirven el mismo sitio. Y si el código no tiene los privilegios de selección habituales en la tabla subyacente, pero funciona a través de la separación de privilegios (por ejemplo, mediante el uso de procedimientos almacenados que se ejecutan como un uid de DB diferente), no se pueden enumerar.

Sin embargo, esto nuevamente tiene una aplicabilidad limitada y no aborda el caso en el que los datos están comprometidos.

Mi solución era cifrar los datos de la sesión con una clave generada aleatoriamente que no se almacena en el servidor en absoluto. De ahí que los datos estén protegidos en reposo. Este enfoque tiene límites: limita la capacidad y sería un PITA de apoyo. Puede haber otros problemas que no haya previsto.

    
respondido por el symcbean 08.09.2016 - 18:29
fuente

Lea otras preguntas en las etiquetas