<?php ini_set( 'session.use_only_cookies', TRUE ); ini_set( 'session.use_trans_sid', FALSE ); ?>Tener en cuenta que el codigo anterior se debe incluir al principio de cada script php pero tambien pueden definirise en php.ini, lo que se busca es que la informacion sid del usuario no pueda obtenerse mediante $_GET['PHPSESSID'] sino solamente a traves de cookies, tambien se especifica a off el session.use_trans_sid para evitar leaking session ID en las URL’s Aparte se debe generar nuevos IDs de sesión para distintos clientes. El programa del lado del servidor nunca debería usar IDs entregados por el browser para un usuario logueado, esto es, una vez que el usuario se loguea en el sistema, éste debería generar automáticamente un nuevo ID de sesión y utilizar éste en el futuro. Desde el código que realiza el login debería utilizarse sesion_regenerate_id() a fin de no utilizar el que por defecto entrega PHP
<?php if(($_POST['user'] == "demasiadovivo") && ($_POST['pass'] == "123456")) { session_regenerate_id(true); $_SESSION['user'] = "demasiadovivo"; } ?>La función session_regenerate_id() crea un nuevo ID de sesión. De ésta forma, por más que hayamos usado un ID insertado por el atacante antes de loguearnos, una vez logueados utilizaremos un ID totalmente distinto y desconocido por el atacante. Otra opción es regenerar los identificadores de sesión para sesiones nuevas. Esto se consigue poniendo una "marca" en las sesiones de la página web. Cada vez que se hace un session_start(), si la sesión no tiene la "marca", cambiamos su identificador por uno nuevo (session_regenerate_id(true);) y desconocido para el atacante. Ejemplo:
<?php session_start(); if (isset($_SESSION['mark']) === false) { session_regenerate_id(true); $_SESSION['mark'] = true; } ?>Cambiar el identificador de sesión siempre que un usuario cambie su estado (autenticado, registrado, ...). Con la anterior medida de protección puede parecer que ya estamos protegidos, pero un atacante puede entrar en la página web, generar una sesión con "marca" y después mandar el identificador de esa sesión al usuario atacado. Así el usuario atacado acabaría con una sesión con "marca" y conocida por el atacante. Por eso, se debe regenerar el identificar de sesión siempre que un usuario realice una acción que le obligue a autenticarse. Ejemplo:
<?php if ($user_logged_in === true) { session_regenerate_id(true); $_SESSION['logged'] = true; } ?>Aviso: es muy importante que sea session_regenerate_id(true); y no session_regenerate_id(); ya que si no eliminamos la sesión antigua, estamos haciendo más fácil los ataques contra la página web al dejar múltiples sesiones válidas abiertas en el servidor.
Definir un tiempo de vida a la variable de sesión de PHP. Después de dar algunas pautas contra los ataques más usuales de robo de las sesiones, otra buena práctica es definir un tiempo de vida a las sesiones para que un usuario logueado no se quede “dormido” con la sesión abierta. En nuestra aplicación tendrá un limite de tiempo y cuando se agote se redireccionará a una página web para su nuevo acceso a la plataforma y creación de una nueva sesión. xxxxxxxx
Definir un tiempo de inactividad de session En el php.ini esta un atributo llamado 'session.cookie_lifetime', si está en 0 va a durar hasta que el navegador se cierre tambien puedes indicar cuanto debe durar la cookie de sesion, en esta línea session.gc_maxlifetime = 1440 que esta dado en segundos, cambias el 1440 por el número de segundos que estimes conveniente. Si no tienes acceso al php.ini puedes utilizar session_set_cookie_params con su parámetro respectivo que es lifetime en este caso se termina sesión cuando el usuario cierra el explorador web:
<?php session_set_cookie_params(0); session_start(); ?>Para que funcione debes eliminar debidamente las cookies de session cuando un usuario termine session. Este script maneja valida el tiempo establecido de vida para una sesión, en caso de que la validación haya expirado destruye la sesión y redirige al usuario al área de login para que vuelva a registrarse , el siguiente código debe colocarse en la página de inicio de sesión
<?php session_start(); $_SESSION['tiempo']=time(); ?>Este script deberá colocarse en toda página que requiera una sesión de usuario autorizada
<?php session_start(); include('archivo.php'); ..... ..... ?>Y este será el contenido de archivo.php que se encargara de cerrar una sesión si es que esta ha expirado de acuerdo a un tiempo establecido por nosotros a conveniencia
<?php $time = 3600; // una hora en mili-segundos // verificamos si existe la sesión // el nombre "session_name" es como ejemplo if(isset($_SESSION["session_name"])) { // verificamos si existe la sesión que se encarga del tiempo // si existe, y el tiempo es mayor que una hora, expiramos la sesión if(isset($_SESSION["expire"]) && time() > $_SESSION["expire"] + $time) { echo''; // también puedes utilizar header(“Location:index.php”); // destruir informacion de session en el server unset($_SESSION["expire"]); unset($_SESSION["session_name"]); session_unset(); session_destroy(); // destruir informacion de session en el cliente $session_cookie_params = session_get_cookie_params(); setcookie(session_name(), '', time() - 24 * 3600, $session_cookie_params['path'], $session_cookie_params['domain'], $session_cookie_params['secure'], $session_cookie_params['httponly']); // Limpiar el array $_SESSION $_SESSION = array(); } // creamos o redefinimos el valor de la variable de session else { $_SESSION["expire"] = time(); } } ?>
Si vas a modificar el php.ini te vale esta información
session.gc_maxlifetime Este valor (por defecto 1440 segundos) define cuánto tiempo se mantendrá viva una sesión PHP sin utilizar. Por ejemplo: un usuario inicia sesión, busca a través de su aplicación o sitio web , por hora, por día. No hay problema. Mientras el tiempo entre sus clics nunca exceda 1.440 segundos. Es un valor de tiempo de espera. Colector de basura la sesión de PHP se ejecuta con una probabilidad definida por session.gc_probability dividido por session.gc_divisor . Por defecto es 1/100, lo que significa que el valor de tiempo de espera anterior se comprueba con una probabilidad de 1 en 100. Si dejas un valor de 100% es decir: gc_probability/gc_divisor = 1/10000 va a hacer que el servidor sobre-cargue a PHP indicando que en todas las peticiones haga una limpieza de las sesiones. Lo mejor en caso de ser un servidor que tiene poca visita colocarlo a que sea un 1% es decir 1/100 (también puede ser un 10% si tu servidor lo estás usando para desarrollar, es decir 1/1000). Si tiene mucha visita lo mejor es colocar a que sea 0.1% es decir 1000/1.
session.cookie_lifetime Este valor (por defecto 0, es decir, hasta el próximo reinicio del navegador) define el tiempo (en segundos) vivirá una cookie de sesión. Suena similar a session.gc_maxlifetime , pero es un enfoque completamente diferente. Este valor define indirectamente el "absoluto" tiempo de vida máximo de una sesión, si el usuario está activo o no. Si este valor se establece en 60, cada sesión termina después de una hora. Al crear mis antiguas aplicaciones en PHP, solía controlar la duración de las sesiones con únicamente un parámetro, session.gc_maxlifetime, que por defecto está ajustado a 1440 segundos (24 minutos), ya que lo cambiaba a 7200 segundos (dos horas, o 120 minutos). Aunque no es una técnica recomendada, solía modificar el parámetro en php.ini. El primer problema era que obligaba a todas las aplicaciones del servidor a permitir que las sesiones duraran 2 horas. El segundo era que una actualización en el servidor producía que la caducidad volviera a 1440 segundos. Es decir, la duración o caducidad de las sesiones no puede dejarse en manos de php.ini, sino de la propia aplicación. Podemos correr el riesgo de modificar ambos parámetros desde php.ini: session.cookie_lifetime 7200 session.gc_maxlifetime 7200 O mejor aún, colocarlos en cada página que utilice sesiones:
<?php ini_set("session.cookie_lifetime","7200"); ini_set("session.gc_maxlifetime","7200"); session_start(); $_SESSION["ejemplo"]="invitado"; ?>Recuerda ponerlo antes de la instrucción “session_start()” y además verificar la probabilidad de gc sea 1/100 Terminar sesión apropiadamente
<?php // destruir información de session en el server session_unset(); session_destroy(); // destruir informacion de session en el cliente $session_cookie_params = session_get_cookie_params(); setcookie(session_name(), '', time() - 24 * 3600, $session_cookie_params['path'], $session_cookie_params['domain'], $session_cookie_params['secure'], $session_cookie_params['httponly']); // Limpiar el array $_SESSION $_SESSION = array(); ?>