PHP

PHP

Tutorial PHP: Configuración de Sesiones

Descubre cómo optimizar la configuración de sesiones HTTP en PHP mediante el archivo php.ini para mejorar la seguridad y eficiencia.

Aprende PHP GRATIS y certifícate

Configuración en php.ini: session.cookie_lifetime, session.save_path, etc.

La configuración de las sesiones en PHP se puede ajustar a través del archivo php.ini, permitiendo controlar múltiples aspectos de su comportamiento. Estas directivas afectan cómo se manejan las sesiones en el servidor y son cruciales para la seguridad y eficiencia de las aplicaciones.

Una de las directivas más importantes es session.cookie_lifetime, que determina el tiempo de vida de la cookie de sesión en el navegador del usuario. Por defecto, su valor es 0, lo que indica que la cookie expirará al cerrar el navegador. Si se establece un valor en segundos, la cookie persistirá durante ese periodo. Por ejemplo:

session.cookie_lifetime = 3600

Con esta configuración, la cookie de sesión permanecerá activa durante una hora (3600 segundos) incluso si el usuario cierra y vuelve a abrir el navegador.

La directiva session.save_path especifica el directorio en el que se almacenan los datos de sesión en el servidor. Es fundamental que este directorio sea seguro y accesible solo por el servidor para prevenir accesos no autorizados. Por ejemplo:

session.save_path = "/var/lib/php/sessions"

Al definir una ruta personalizada, se garantiza que las sesiones se almacenen en un lugar controlado, y es importante verificar que el servidor web tenga permisos de lectura y escritura en ese directorio.

Otra configuración relevante es session.use_strict_mode. Cuando se habilita, PHP rechaza identificadores de sesión no válidos, lo que mejora la seguridad al prevenir la aceptación de sesiones no inicializadas por el sistema. Para activarla:

session.use_strict_mode = 1

La directiva session.gc_maxlifetime define el tiempo máximo de vida que una sesión puede permanecer inactiva antes de ser eliminada por el recolector de basura de PHP. Esto ayuda a liberar recursos y a mantener la seguridad al cerrar sesiones inactivas. Por ejemplo:

session.gc_maxlifetime = 1440

Aquí, las sesiones expirarán después de 24 minutos de inactividad (1440 segundos).

Las directivas session.gc_probability y session.gc_divisor controlan la probabilidad de que se ejecute el proceso de recolección de sesiones caducadas. La probabilidad se calcula como gc_probability/gc_divisor. Por defecto, suelen tener los valores:

session.gc_probability = 1
session.gc_divisor = 1000

Esto significa que hay un 0.1% de probabilidad en cada solicitud de que se ejecute la limpieza de sesiones expiradas. Ajustar estos valores puede ser útil en aplicaciones con alto tráfico para controlar el rendimiento.

La configuración session.cookie_secure determina si la cookie de sesión se enviará solo a través de conexiones seguras HTTPS. Es recomendable habilitar esta opción en entornos de producción que utilicen SSL/TLS para proteger la información de sesión:

session.cookie_secure = 1

Por último, session.cookie_httponly indica que la cookie de sesión no estará accesible mediante scripts del lado del cliente como JavaScript, reduciendo la exposición a ataques de tipo Cross-Site Scripting (XSS):

session.cookie_httponly = 1

Configurar adecuadamente estas directivas en php.ini es esencial para controlar el comportamiento y la seguridad de las sesiones en una aplicación PHP. Cada aplicación puede tener necesidades diferentes, por lo que es importante ajustar estos valores acorde a los requerimientos específicos y las mejores prácticas de seguridad.

Identificadores de sesión y su seguridad (rotación de sesión)

En PHP, el identificador de sesión es una cadena única que permite asociar una sesión con un usuario específico. Este identificador se almacena comúnmente en una cookie denominada PHPSESSID y es esencial para mantener el estado entre las peticiones HTTP, que por naturaleza son sin estado.

La seguridad del identificador de sesión es crucial, ya que si un atacante logra obtenerlo, podría secuestrar la sesión y acceder a información sensible. Por ello, es fundamental garantizar que los identificadores de sesión sean impredecibles y difíciles de adivinar.

Una medida de seguridad importante es la rotación del identificador de sesión al momento de realizar acciones críticas, como el inicio de sesión o cambios de privilegios. Al regenerar el ID de sesión, se minimiza el riesgo de ataques de fijación de sesión y se asegura que cualquier identificador anterior sea inválido.

Para regenerar el identificador de sesión en PHP, se utiliza la función session_regenerate_id(). Esta función crea un nuevo ID y, al pasarle el parámetro true, elimina la sesión anterior del almacenamiento:

<?php
session_start();

// Después de autenticar al usuario
if ($usuarioAutenticado) {
    // Regenerar el ID de sesión para prevenir fijación de sesión
    session_regenerate_id(true);
    $_SESSION['usuario'] = $nombreDeUsuario;
    echo "Bienvenido, $nombreDeUsuario\n";
}

En este ejemplo, tras validar las credenciales del usuario, se llama a session_regenerate_id(true) para generar un nuevo identificador de sesión y asegurar que el antiguo no pueda ser reutilizado.

Además de regenerar el ID al inicio de sesión, es recomendable realizar una rotación periódica durante la sesión para aumentar la seguridad. Esto se puede lograr controlando el tiempo transcurrido desde la última regeneración:

<?php
session_start();

if (!isset($_SESSION['ultima_actividad'])) {
    $_SESSION['ultima_actividad'] = time();
} elseif (time() - $_SESSION['ultima_actividad'] > 600) {
    // Regenerar el ID de sesión cada 10 minutos
    session_regenerate_id(true);
    $_SESSION['ultima_actividad'] = time();
}

Esta práctica limita el tiempo durante el cual un identificador de sesión comprometido podría ser utilizado por un atacante, reduciendo la ventana de oportunidad para un posible secuestro de sesión.

Es importante también configurar el archivo php.ini para fortalecer la seguridad de las sesiones. La directiva session.use_strict_mode es especialmente útil, ya que obliga a PHP a aceptar únicamente identificadores de sesión creados por el servidor:

session.use_strict_mode = 1

Al activar el modo estricto, se previene que un atacante reutilice identificadores de sesión no válidos o forzados, mejorando la integridad de las sesiones.

Otra configuración esencial es session.use_only_cookies, que indica a PHP que solo utilice cookies para manejar los identificadores de sesión, evitando que se pasen por la URL u otros métodos inseguros:

session.use_only_cookies = 1

Esto reduce el riesgo de que el identificador de sesión sea expuesto en registros del servidor o enlaces compartidos, protegiendo la información del usuario.

Para incrementar aún más la seguridad, se deben configurar las cookies de sesión con las banderas HttpOnly y Secure. La bandera HttpOnly impide que scripts del lado del cliente accedan a la cookie de sesión, protegiendo contra ataques XSS. La bandera Secure asegura que la cookie solo se transmita a través de conexiones HTTPS:

session.cookie_httponly = 1
session.cookie_secure = 1

Implementar estas configuraciones y prácticas en el manejo de los identificadores de sesión es vital para desarrollar aplicaciones PHP seguras. La combinación de una correcta configuración y la rotación periódica del ID de sesión contribuye significativamente a proteger las sesiones contra accesos no autorizados y ataques malintencionados.

Recomendaciones para evitar secuestro de sesión (session hijacking)

El secuestro de sesión es una de las amenazas más comunes en aplicaciones web, donde un atacante obtiene acceso no autorizado a la sesión de un usuario legítimo. Para prevenir este tipo de ataques en PHP, es esencial seguir una serie de prácticas y configuraciones que fortalezcan la seguridad de las sesiones.

Una medida fundamental es asegurar que todas las comunicaciones entre el cliente y el servidor se realicen a través de conexiones HTTPS. El cifrado que proporciona SSL/TLS evita que terceros intercepten y lean los datos transmitidos, incluyendo los identificadores de sesión. Para reforzar esta medida, se debe configurar la cookie de sesión para que solo se transmita por conexiones seguras:

session.cookie_secure = 1

Además, es crucial que las cookies de sesión estén protegidas contra el acceso mediante scripts del lado del cliente. Esto se logra estableciendo la bandera HttpOnly, evitando que herramientas como JavaScript puedan acceder a la cookie y potencialmente exponer el identificador de sesión:

session.cookie_httponly = 1

Evitar exponer el identificador de sesión en la URL es otra práctica recomendable. Cuando los IDs de sesión se pasan por la URL, quedan registrados en el historial del navegador, los logs del servidor y pueden ser compartidos accidentalmente si el usuario copia y pega enlaces. Para asegurarse de que PHP solo utilice cookies para manejar sesiones, se debe configurar:

session.use_only_cookies = 1

Implementar una rotación periódica del identificador de sesión ayuda a minimizar el tiempo en que un ID de sesión podría ser explotado si es comprometido. Como se indicó anteriormente, la función session_regenerate_id(true) permite generar un nuevo ID de sesión y eliminar el antiguo:

<?php
session_start();

// Regenerar el ID de sesión cada cierto tiempo
if (!isset($_SESSION['ultima_regeneracion'])) {
    $_SESSION['ultima_regeneracion'] = time();
} elseif (time() - $_SESSION['ultima_regeneracion'] > 300) {
    // Regenerar cada 5 minutos
    session_regenerate_id(true);
    $_SESSION['ultima_regeneracion'] = time();
}

Es importante limitar el tiempo de vida de las sesiones inactivas. Establecer una política de cierre de sesión automática tras un período de inactividad reduce el riesgo de que sesiones abandonadas sean aprovechadas por atacantes:

<?php
session_start();

$tiempo_inactividad = 600; // 10 minutos

if (isset($_SESSION['ultimo_acceso'])) {
    $inactividad = time() - $_SESSION['ultimo_acceso'];
    if ($inactividad > $tiempo_inactividad) {
        session_unset();     // Liberar variables de sesión
        session_destroy();   // Destruir la sesión
        echo "Su sesión ha expirado por inactividad.\n";
        exit();
    }
}
$_SESSION['ultimo_acceso'] = time();

Validar información adicional del usuario, como su agente de usuario o dirección IP, puede añadir una capa extra de seguridad. Sin embargo, hay que ser cauteloso, ya que factores como las direcciones IP dinámicas o las conexiones móviles pueden causar problemas de legitimidad. Un ejemplo de validación basada en el agente de usuario:

<?php
session_start();

if (!isset($_SESSION['agente_usuario'])) {
    $_SESSION['agente_usuario'] = $_SERVER['HTTP_USER_AGENT'];
} elseif ($_SESSION['agente_usuario'] !== $_SERVER['HTTP_USER_AGENT']) {
    session_unset();
    session_destroy();
    echo "Posible secuestro de sesión detectado.\n";
    exit();
}

La implementación de tokens CSRF (Cross-Site Request Forgery) en formularios y acciones sensibles previene que terceros puedan realizar acciones en nombre del usuario sin su consentimiento. Al generar un token único por sesión y verificarlo en cada solicitud, se asegura que las peticiones provienen del usuario legítimo:

<?php
// Al generar el formulario
if (empty($_SESSION['token_csrf'])) {
    $_SESSION['token_csrf'] = bin2hex(random_bytes(32));
}
$token = $_SESSION['token_csrf'];
echo "<form method='post'>\n";
echo "<input type='hidden' name='token_csrf' value='$token'>\n";
echo "<input type='submit' value='Enviar'>\n";
echo "</form>\n";

// Al procesar el formulario
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!hash_equals($_SESSION['token_csrf'], $_POST['token_csrf'])) {
        // Token no válido
        echo "Error de validación del token CSRF.\n";
        exit();
    }
    // Procesar acción segura
}

Es recomendable almacenar las sesiones en un almacenamiento seguro y aislado, como una base de datos o un sistema de caché dedicado, en lugar de usar el almacenamiento de archivos por defecto. Esto permite un control más preciso y protege mejor los datos de sesión.

Finalmente, mantener el software actualizado es esencial. Las nuevas versiones de PHP y las extensiones relacionadas suelen incluir parches de seguridad y mejoras que ayudan a proteger contra vulnerabilidades conocidas.

En resumen, combinar configuraciones adecuadas, buenas prácticas de programación y medidas de seguridad adicionales es clave para prevenir el secuestro de sesiones en aplicaciones PHP. La conciencia y el esfuerzo continuo en materia de seguridad garantizarán que las sesiones de los usuarios estén protegidas frente a posibles amenazas.

Para seguir leyendo hazte Plus

¿Ya eres Plus? Accede a la app

20 % DE DESCUENTO

Plan mensual

19.00 /mes

15.20 € /mes

Precio normal mensual: 19 €
58 % DE DESCUENTO

Plan anual

10.00 /mes

8.00 € /mes

Ahorras 132 € al año
Precio normal anual: 120 €
Aprende PHP GRATIS online

Todas las lecciones de PHP

Accede a todas las lecciones de PHP y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Php

PHP

Introducción Y Entorno

Instalación Y Primer Programa De Php

PHP

Introducción Y Entorno

Tipos De Datos, Variables Y Constantes

PHP

Sintaxis

Operadores Y Expresiones

PHP

Sintaxis

Estructuras De Control

PHP

Sintaxis

Funciones Y Llamada De Funciones

PHP

Sintaxis

Cadenas De Texto Y Manipulación

PHP

Sintaxis

Manejo De Números

PHP

Sintaxis

Manejo De Fechas Y Tiempo

PHP

Sintaxis

Manejo De Arrays

PHP

Sintaxis

Introducción A La Poo En Php

PHP

Programación Orientada A Objetos

Clases Y Objetos

PHP

Programación Orientada A Objetos

Constructores Y Destructores

PHP

Programación Orientada A Objetos

Herencia

PHP

Programación Orientada A Objetos

Encapsulación

PHP

Programación Orientada A Objetos

Polimorfismo

PHP

Programación Orientada A Objetos

Interfaces

PHP

Programación Orientada A Objetos

Traits

PHP

Programación Orientada A Objetos

Namespaces

PHP

Programación Orientada A Objetos

Autoloading De Clases

PHP

Programación Orientada A Objetos

Manejo De Errores Y Excepciones

PHP

Programación Orientada A Objetos

Manejo De Archivos

PHP

Programación Orientada A Objetos

Patrones De Diseño

PHP

Programación Orientada A Objetos

Introducción A Los Formularios En Php

PHP

Formularios

Procesamiento De Datos De Formularios

PHP

Formularios

Manejo De Archivos En Formularios

PHP

Formularios

Redirecciones Y Retroalimentación Al Usuario

PHP

Formularios

Formularios Dinámicos Y Separación De Lógica

PHP

Formularios

Introducción A La Persistencia En Php

PHP

Persistencia

Conexión A Bases De Datos

PHP

Persistencia

Consultas Y Operaciones Crud

PHP

Persistencia

Gestión De Transacciones

PHP

Persistencia

Manejo De Errores Y Excepciones En Base De Datos

PHP

Persistencia

Patrones De Acceso A Datos

PHP

Persistencia

Concepto De Sesiones En Php

PHP

Sesiones Y Cookies

Configuración De Sesiones

PHP

Sesiones Y Cookies

Cookies

PHP

Sesiones Y Cookies

Manejo Avanzado De Sesiones Y Cookies

PHP

Sesiones Y Cookies

Principales Vulnerabilidades En Php

PHP

Seguridad

Seguridad En Formularios Y Entrada De Datos

PHP

Seguridad

Protección Frente A Inyección Sql

PHP

Seguridad

Gestión De Contraseñas Y Cifrado

PHP

Seguridad

Seguridad En Sesiones Y Cookies

PHP

Seguridad

Configuraciones De Php Para Seguridad

PHP

Seguridad

Introducción Al Testing En Php

PHP

Testing

Phpunit

PHP

Testing

Cobertura De Código En Testing

PHP

Testing

Test Doubles (Mocks, Stubs, Fakes, Spies)

PHP

Testing

Pruebas De Integración Y Funcionales

PHP

Testing

Accede GRATIS a PHP y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender el propósito y uso de las directivas session.cookie_lifetime y session.save_path.
  • Configurar session.gc_maxlifetime y las probabilidades de recolección de basura.
  • Activar el modo de sesión use_strict_mode para mejorar la seguridad.
  • Asegurar las sesiones utilizando las cookies con las banderas Secure y HttpOnly.
  • Implementar la regeneración de identificadores de sesión en PHP.
  • Aplicar buenas prácticas para prevenir el secuestro de sesión (session hijacking).