PHP:$_SESSION - ¿Cuáles son las ventajas y desventajas de almacenar datos usados ​​temporalmente en la variable $_SESSION?

StackOverflow https://stackoverflow.com/questions/77826

  •  09-06-2019
  •  | 
  •  

Pregunta

Una cosa que he empezado a hacer más a menudo últimamente es recuperando algunos datos al comienzo de una tarea y almacenarlo en $_SESSION['myDataForTheTask'].

Ahora parece muy conveniente hacerlo, pero no sé nada sobre el rendimiento, los riesgos de seguridad o similares al utilizar este enfoque.¿Es algo que hacen regularmente programadores con más experiencia o es más bien algo que hacen los aficionados?

Por ejemplo:

if (!isset($_SESSION['dataentry']))
{
    $query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=" . mysql_real_escape_string($_GET['wave_id']);
    $result_taskinfo = $db->query($query_taskinfo);
    $row_taskinfo = $result_taskinfo->fetch_row();

        $dataentry = array("pcode" => $row_taskinfo[0], "modules" => $row_taskinfo[1], "data_id" => 0, "wavenum" => $row_taskinfo[2], "prequest" => FALSE, "highlight" => array());

        $_SESSION['dataentry'] = $dataentry;
}
¿Fue útil?

Solución

Bueno, las variables de sesión son realmente una de las únicas formas (y probablemente la más eficiente) de tener estas variables disponibles durante todo el tiempo que el visitante esté en el sitio web; no hay una forma real de que un usuario las edite (aparte de un exploit en su código, o en el intérprete PHP) por lo que son bastante seguros.

Es una buena manera de almacenar configuraciones que el usuario puede cambiar, ya que puede leer la configuración de la base de datos una vez al comienzo de una sesión y está disponible para toda la sesión, solo necesita realizar más llamadas a la base de datos si la configuración se cambian y, por supuesto, como se muestra en su código, es trivial saber si las configuraciones ya existen o si es necesario extraerlas de la base de datos.

No se me ocurre ninguna otra forma de almacenar variables temporales de forma segura (ya que las cookies se pueden modificar fácilmente y esto no será deseable en la mayoría de los casos), por lo que $_SESSION sería el camino a seguir.

Otros consejos

El mecanismo $_SESSION utiliza cookies.

En el caso de Firefox (y tal vez del nuevo IE, no lo comprobé yo mismo) eso significa que la sesión se comparte entre pestañas abiertas.Eso no es algo que esperes por defecto.Y significa que la sesión ya no es "algo específico de una única ventana/usuario".

Por ejemplo, si abrió dos pestañas para acceder a su sitio y luego inició sesión como root usando la primera pestaña, obtendrá privilegios de root en la otra.

Esto es realmente inconveniente, especialmente si codifica un cliente de correo electrónico u otra cosa (como una tienda electrónica).En este caso, tendrá que gestionar las sesiones manualmente o introducir una clave regenerada constantemente en la URL o hacer otra cosa.

Utilizo la variable de sesión todo el tiempo para almacenar información para los usuarios.No he visto ningún problema con el rendimiento.Los datos de la sesión se extraen en función de la cookie (o PHPSESSID si tienes las cookies desactivadas).No veo que sea un riesgo de seguridad mayor que cualquier otra autenticación basada en cookies, y probablemente sea más seguro que almacenar los datos reales en la cookie de los usuarios.

Sólo para informarle que tiene un problema de seguridad con su declaración SQL:

SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".$_GET['wave_id'];

Debería NUNCA, REPITO NUNCA, tome los datos proporcionados por el usuario y utilícelos para ejecutar una declaración SQL sin desinfectarlos primero.Lo envolvería entre comillas y agregaría la función. mysql_real_escape_string().Eso te protegerá de la mayoría de los ataques.Entonces tu línea se vería así:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id='".mysql_real_escape_string($_GET['wave_id'])."'";

Hay algunos factores que querrás considerar al decidir dónde almacenar datos temporales.El almacenamiento de sesiones es excelente para datos específicos de un solo usuario.Si encuentra que el controlador de almacenamiento de sesión predeterminado basado en archivos es ineficiente, puede implementar algo más, posiblemente usando una base de datos o un backend tipo Memcache.Ver session_set_save_handler para más información.

Considero que es una mala práctica almacenar datos comunes en la sesión de un usuario.Hay mejores lugares para almacenar datos a los que accederán con frecuencia varios usuarios y, al almacenar estos datos en la sesión, duplicará los datos para cada usuario que los necesite.En su ejemplo, puede configurar un tipo diferente de motor de almacenamiento para los datos de esta ola (basado en wave_id) que NO esté vinculado específicamente a la sesión de un usuario.De esa manera, extraerá los datos una vez y los almacenará en algún lugar donde varios usuarios puedan acceder a los datos sin necesidad de volver a extraerlos.

Si está ejecutando en su propio servidor, o en un entorno donde nadie puede espiar sus archivos/memoria en el servidor, los datos de la sesión están seguros.Se almacenan en el servidor y solo se envía una cookie de identificación al cliente.El problema es si otras personas pueden arrebatar la galleta y hacerse pasar por otra persona, claro.Usar HTTPS y asegurarse de no incluir el ID de sesión en las URL debería mantener a sus usuarios a salvo de la mayoría de esos problemas.(Es posible que XSS aún se use para capturar cookies si no tiene cuidado, consulte Publicación de Jeef Atwood sobre esto también.)

En cuanto a qué almacenar en una variable de sesión, coloque sus datos allí si desea consultarlos nuevamente en otra página, como una cesta de compras, pero no los coloque allí si son solo datos temporales utilizados para producir el resultado de esto. página, como una lista de etiquetas para la publicación vista actualmente.Las sesiones son para datos persistentes por usuario.

Otra forma de mejorar la validación de entrada es convertir la variable _GET['wave_id']:

$query_taskinfo = "SELECT participationcode, modulearray, wavenum FROM mng_wave WHERE wave_id=".(int)$_GET['wave_id']." LIMIT 1";

Supongo que wave_id es un número entero y que solo hay una respuesta.

Voluntad

Algunas otras desventajas del uso de sesiones:

  1. $_SESSION los datos caducan después sesión.gc_maxlifetime segundos de inactividad.
  2. Tendrás que acordarte de llamar session_start() para cada script que utilizará los datos de la sesión.
  3. Escalar el sitio web mediante el equilibrio de carga en varios servidores podría ser un problema porque el usuario deberá ser dirigido al mismo servidor cada vez.Resuelve esto con "Sticky Sessions".

Los elementos $_SESSION se almacenan en la sesión, que, de forma predeterminada, se guarda en el disco.No es necesario crear su propia matriz y colocarla en una entrada de matriz de 'entrada de datos' como lo hizo.Puedes usar $_SESSION['pcode'], $_SESSION['modules'] y así sucesivamente.

Como dije, la sesión se almacena en el disco y un puntero a la sesión se almacena en una cookie.Por lo tanto, el usuario no puede acceder fácilmente a los datos de la sesión.

En mi opinión, es perfectamente aceptable almacenar cosas en la sesión.Es una excelente manera de hacer que los datos sean persistentes.También es, en muchos casos, más seguro que almacenar todo en cookies.Aquí hay algunas preocupaciones:

  • Es posible que alguien se apropie de una sesión, por lo que si va a utilizarla para realizar un seguimiento de la autorización del usuario, tenga cuidado.Leer este para más información.
  • Puede ser una forma muy vaga de conservar datos.No incluya todo en la sesión para no tener que consultarlo más tarde.
  • Si va a almacenar objetos en la sesión, sus archivos de clase deberán incluirse antes de que se inicie la sesión en la siguiente solicitud o deberá haber configurado un cargador automático.

Zend Framework tiene una biblioteca útil para la gestión de datos de sesiones que ayuda con la caducidad y la seguridad (para cosas como captchas).También tienen una útil explicación de las sesiones.Ver http://framework.zend.com/manual/en/zend.session.html

He encontrado que las sesiones son muy útiles, pero hay algunas cosas a tener en cuenta:

1) Que PHP puede almacenar sus sesiones en una carpeta tmp u otro directorio al que otros usuarios puedan acceder en su servidor.Puede cambiar el directorio donde se almacenan las sesiones yendo al archivo php.ini.

2) Si está configurando un sistema de alto valor que necesita una seguridad muy estricta, es posible que desee cifrar los datos antes de enviarlos a la sesión y descifrarlos para usarlos.Nota:Esto podría generar demasiada sobrecarga dependiendo de la capacidad del tráfico/servidor.

3) He encontrado que session_destroy();no elimina la sesión de inmediato, aún debe esperar a que el recolector de basura de PHP limpie las sesiones.Puede cambiar la frecuencia con la que se ejecuta el recolector de basura en el archivo php.ini.Pero todavía no parece muy fiable, más información. http://www.captain.at/howto-php-sessions.php

¿Quizás quieras considerar qué tan REST-ful es esto?

es decir.consulte el párrafo "Comunicar sin estado" en "Una breve introducción a REST"...

"El descanso exige que ese estado se convierta en estado de recursos o se mantenga en el cliente.En otras palabras, un servidor no debería tener que retener algún tipo de estado de comunicación para cualquiera de los clientes con los que se comunica más allá de una sola solicitud ".

(o cualquiera de los otros enlaces en wikipedia para DESCANSAR)

Entonces, en su caso, 'wave_id' es un recurso sensato para OBTENER, pero ¿realmente desea almacenarlo en la SESIÓN?Seguramente memcached Cuál es su solución para almacenar en caché el recurso del objeto?

Utilizo este enfoque bastante, no veo ningún problema en ello.A diferencia de las cookies, los datos no se almacenan en el lado del cliente, lo que suele ser un gran error.

Sin embargo, como todo, tenga cuidado de desinfectar siempre la entrada del usuario, especialmente si coloca la entrada del usuario en la variable $_SESSION y luego usa esa variable en una consulta SQL.

Esto es algo bastante común y la sesión generalmente será más rápida que las visitas continuas a la base de datos.También son razonablemente seguros, ya que los desarrolladores de PHP han trabajado duro para evitar el secuestro de sesión.

El único problema es que debes recordar reconstruir la entrada de la sesión cuando algo cambie.Y, si un usuario que no sea el propietario de la sesión cambia algo que resulte en la necesidad de actualizar esta clave, no existe una manera fácil de notificar al sistema que actualice esta clave de sesión.Posiblemente no sea gran cosa, pero es algo que debes tener en cuenta.

$_SESSION es muy útil en seguridad, ya que es una forma del lado del servidor para almacenar información mientras un usuario está activamente en sus páginas, por lo tanto, es difícil de piratear a menos que su archivo php o servidor real tenga debilidades que puedan explotarse.Una muy buena implementación es almacenar una variable para confirmar que el usuario ha iniciado sesión y solo permitir que se realicen acciones si se confirma que ha iniciado sesión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top