¿Necesita cifrar los datos de la sesión?

9

Encontré una clase de administración de sesión en PHP que encripta los datos de la sesión en la carpeta de almacenamiento de la sesión (es decir, /tmp ) y se puede descifrar más adelante en su script con una clave. Me preguntaba si es realmente necesario? Si ya está realizando una sesión de prevención de secuestro como este ejemplo (simplificado):

session_start();

if (isset($_SESSION['fingerprint']))
    if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'].'SECRETSALT'))          
        exit; // prompt for password
else
    $_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'].'SECRETSALT');

¿Aún necesita cifrar los datos de su sesión? ¿O solo es necesario el cifrado si está almacenando información confidencial a través de sesiones (por ejemplo, información personal, número de CC, credenciales)?

Además, si está validando si un usuario ha iniciado sesión o no de una manera simple como esta:

// login.php

if ($_POST['password'] == $db_password)
{
    $_SESSION['logged_in'] = true;
    redirect_to_protected_area();
}
else
    // show login again

// protected_area.php

if (!isset($_SESSION['logged_in']) OR !$_SESSION['logged_in'])
    exit; // prompt for password
else
    // show protected area

¿Qué daño se puede hacer si los datos de la sesión no están encriptados y un pirata informático vio los datos a simple vista (es decir, el hash md5 de la huella digital y el logged_in = true )? ¿Puede realmente iniciar sesión él mismo o primero debe "crackear" el md5?

Nota: md5 se usó para simplificar el ejemplo, se utiliza un hashing mucho mejor en la vida real.

    
pregunta IMB 19.08.2012 - 19:55
fuente

4 respuestas

7

No necesitas cifrarlo. A lo sumo, el cifrado es una forma de ofuscación. Está colocando la clave en el mismo sistema que los datos, por lo que siempre se puede encontrar y extraer.

Si está configurado para cifrarlo, en realidad es bastante posible hacerlo dentro de PHP sin modificar cada uso de $_SESSION . Puede usar la clase SessionHandler para anular el manejo normal de las sesiones. La documentación proporciona una explicación simple de cómo puede cifrar los datos de sesión.

Sin embargo, necesitará una forma de crear y almacenar la clave en toda la sesión. Obviamente, esto no se puede hacer a través del administrador de sesión, de lo contrario estaría distribuyendo la clave con el texto cifrado. Mi sugerencia sería utilizar un caché en memoria, como APC o memcache , donde el nombre de la clave en el caché es el ID de la sesión.

    
respondido por el Polynomial 19.08.2012 - 22:32
fuente
9

Si está utilizando un marco web razonable (uno que tiene un diseño medio decente), no necesita cifrar los datos de la sesión. Eso realmente debería ser responsabilidad del marco.

Sin embargo, si está utilizando PHP, no está utilizando un marco web razonable. PHP es un problema infantil para la seguridad, de muchas maneras. Una de esas formas es que, de forma predeterminada, almacena los datos de la sesión en /tmp . En algunos servicios de alojamiento compartido, /tmp puede compartirse entre los usuarios. Por lo tanto, PHP está almacenando los datos de la sesión en una ubicación donde otros pueden verlos, sin autorización. Esa es una falla de diseño malo, pero bueno, PHP está lleno de fallas de diseño malo, así es como es la vida con PHP.

Por lo tanto, si está utilizando PHP en un servicio de alojamiento compartido (donde /tmp es accesible para otros), sí, debe cifrar los datos de la sesión. Una forma de hacerlo es usar el enlace session_set_save_handler() para encriptar los datos de la sesión . Asegúrese de usar un cifrado sólido (use el cifrado autenticado, evite las trampas comunes de cifrado) con una buena administración de claves (por el amor de Dios, no almacene la clave de cifrado en /tmp ni en ningún otro lugar que otros clientes de su servicio de alojamiento compartido puedan ver ).

O, aloje su aplicación PHP en una máquina dedicada (por ejemplo, una máquina virtual dedicada, un VPS, una máquina física dedicada), y no permita que nadie en quien confíe inicie sesión en esa máquina. O, si de alguna manera estaba seguro de que no está almacenando nada sensible en el almacén de sesiones, no necesita cifrar los datos de la sesión (pero esto es frágil durante el mantenimiento, ya que sería fácil para otra persona agregar una función). en el futuro, eso significa agregar información confidencial al almacén de la sesión sin darse cuenta de las consecuencias para la seguridad).

Pero realmente, una mejor respuesta es: use un marco web serio y bien diseñado. Los amigos no permiten que sus amigos usen PHP para problemas críticos de seguridad. Consulte, por ejemplo, publicación del blog de Jeff Atwood sobre este tema .

    
respondido por el D.W. 20.08.2012 - 08:03
fuente
3

No tiene mucho sentido si la clave está almacenada en el servidor, pero la clave puede provenir del navegador / usuario. Es más difícil acceder a la clave en este escenario (siempre que sea sobre SSL) incluso con algún acceso al servidor / código fuente.

Los datos de la sesión pueden almacenarse en el sistema de archivos / en una base de datos y, por lo tanto, persistir en las copias de seguridad. Además, en un sistema compartido, dependiendo de cómo esté configurado, esto proporciona seguridad en profundidad para los datos de sesión, donde una cuenta de usuario se asigna a un sitio, es fácil restringir el acceso ssh / ftp, pero restringiendo el acceso de PHP a árboles de directorios específicos. es un poco más complejo (hay algunas formas de evitar open_base_dir); para el alojamiento de gama baja, simplemente no tiene sentido financiero ejecutar cada servidor web como un uid separado / grupos FPM separados para cada sitio.

Si bien nadie en su sano juicio debería estar almacenando los detalles de la tarjeta de crédito en un sistema de este tipo, ¿qué sucede si solo quiere un extremo sencillo para invocar ocasionalmente otros servicios? ¿Disponibilidad / rendimiento de sondeo de otro servidor a través de ssh, enviar un SMS o acceder a un buzón? En estos casos, es muy posible que pueda mantener temporalmente un token de autenticación / clave de cifrado / identificador de sesión remota dentro de la sesión.

Si bien es trivial restringir el acceso de escritura a los archivos de PHP src a un pequeño grupo de usuarios otro que no sea el uid del servidor web, el uid del servidor web debe poder escribir los datos de la sesión. Una vez que se autentica a un usuario, la autorización generalmente se basa en la identificación de usuario autenticada almacenada en la sesión; por lo tanto, esto puede ser parte de una solución para proteger contra la escalada de privilegios (necesita otros componentes no mencionados en la publicación).

Ayudará a la seguridad en algunos casos perimetrales según cómo se administre la clave.

    
respondido por el symcbean 21.08.2012 - 10:54
fuente
0

Sería menos complicado utilizar cookies para almacenar solo un ID de sesión. El servidor debe recordar qué usuario pertenece a qué sesión y qué permisos tiene cada usuario. Este diseño tiene la desventaja de que hace que el balanceo de carga sea menos efectivo porque los datos de la sesión deben comunicarse entre todas las instancias de la aplicación.

Un mejor diseño sería permitir que los nodos de inicio de sesión realicen la autenticación y busquen los permisos de los usuarios en la base de datos. Luego, estos datos se devuelven al cliente como un token firmado criptográficamente, que se puede almacenar en una cookie o en una URL. Firmar este token es obligatorio ya que el cifrado no impide la manipulación del token. Es crítico entonces que cada servicio verifique la firma antes de actuar en ella. En realidad, esta es la idea central entre Fichas web de JSON

    
respondido por el MauganRa 12.10.2017 - 15:52
fuente

Lea otras preguntas en las etiquetas