PHP

PHP

Tutorial PHP: Seguridad en sesiones y cookies

PHP: Aprende a configurar cookies seguras con HTTPOnly y Secure para proteger tus aplicaciones web de ataques como XSS y CSRF eficientemente.

Aprende PHP GRATIS y certifícate

Configuración segura de cookies (HTTPOnly, Secure)

La seguridad en el manejo de cookies es esencial para proteger las aplicaciones web de ataques comunes. Al configurar cookies en PHP, es fundamental establecer correctamente los atributos HTTPOnly y Secure para mitigar riesgos como el robo de sesiones y la intercepción de datos.

El atributo HTTPOnly indica al navegador que la cookie no debe estar accesible mediante JavaScript. Esto previene ataques de Cross-Site Scripting (XSS), donde un atacante podría inyectar código JavaScript para acceder a las cookies de sesión. Para establecer una cookie con el atributo HTTPOnly en PHP, se puede utilizar la función setcookie() con el parámetro 'httponly' establecido en true. A partir de PHP 7.3, es recomendable utilizar el array de opciones:

<?php
setcookie('nombre_cookie', 'valor', [
    'expires' => time() + 3600, // Expira en una hora
    'httponly' => true,
]);

En este ejemplo, la cookie no será accesible a través de scripts del lado del cliente, mejorando la seguridad de la sesión.

El atributo Secure indica que la cookie solo se enviará al servidor si la conexión es segura (HTTPS). Esto evita que las cookies sean transmitidas a través de conexiones no cifradas, reduciendo el riesgo de que sean interceptadas por un atacante. Para establecer el atributo Secure, se añade 'secure' => true en las opciones de la cookie:

<?php
setcookie('nombre_cookie', 'valor', [
    'expires' => time() + 3600,
    'secure' => true,
    'httponly' => true,
]);

Es importante asegurarse de que el sitio web esté utilizando HTTPS antes de habilitar este atributo, ya que de lo contrario, la cookie no se enviará al servidor.

Además de HTTPOnly y Secure, es relevante considerar el atributo SameSite, que añade una capa adicional de seguridad ante ataques de Cross-Site Request Forgery (CSRF). Este atributo puede ser 'Lax', 'Strict' o 'None'. Por ejemplo:

<?php
setcookie('nombre_cookie', 'valor', [
    'expires' => time() + 3600,
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict',
]);

Al establecer 'samesite' => 'Strict', la cookie no se enviará en solicitudes de terceros, lo que mejora la protección contra CSRF.

Para maximizar la seguridad, se recomienda configurar las cookies de la siguiente manera:

  • 'secure' => true para asegurar que las cookies solo se envíen por HTTPS.
  • 'httponly' => true para evitar acceso desde JavaScript.
  • 'samesite' => 'Strict' o 'Lax' según las necesidades de la aplicación.
  • 'expires' o 'max-age': establecer un tiempo apropiado de expiración.

Ejemplo de configuración segura de cookies:

<?php
setcookie('session_id', session_id(), [
    'expires' => time() + 3600,
    'path' => '/',
    'domain' => 'tu-dominio.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

Al iniciar una sesión, es importante asegurarse de que las cookies de sesión también estén configuradas de forma segura. Podemos configurar los parámetros antes de llamar a session_start():

<?php
session_set_cookie_params([
    'lifetime' => 3600,
    'path' => '/',
    'domain' => 'tu-dominio.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
session_start();

Esto garantiza que la cookie de sesión utilizará los atributos Secure, HTTPOnly y SameSite, protegiendo la sesión del usuario.

Regeneración de ID de sesión tras inicio de sesión

Para fortalecer la seguridad en aplicaciones PHP, es esencial regenerar el ID de sesión después de que un usuario inicie sesión correctamente. Esto previene ataques de fijación de sesión, donde un atacante podría predecir o fijar el ID de sesión antes del inicio de sesión del usuario.

Al regenerar el ID de sesión, se crea una nueva identificación única, y la anterior queda inválida. Esto asegura que cualquier ID de sesión expuesto o interceptado antes de la autenticación no pueda ser utilizado maliciosamente. En PHP, se utiliza la función session_regenerate_id() para este propósito.

Ejemplo de cómo regenerar el ID de sesión tras el inicio de sesión:

<?php
// Iniciar o reanudar la sesión existente
session_start();

// Verificar las credenciales del usuario (ejemplo simplificado)
if ($usuarioValido) {
    // Regenerar el ID de sesión para prevenir fijación de sesión
    session_regenerate_id(true);

    // Almacenar información en la sesión
    $_SESSION['usuario'] = $nombreDeUsuario;

    echo "Bienvenido, " . $_SESSION['usuario'] . "\n";
} else {
    echo "Credenciales incorrectas\n";
}

En este código:

  • Después de session_start(), se verifica si el usuario es válido.
  • La función session_regenerate_id(true) genera un nuevo ID de sesión y elimina el anterior.
  • Se guarda el nombre de usuario en $_SESSION para mantener el estado de autenticado.

Es importante usar el parámetro true en session_regenerate_id(true) para eliminar el ID de sesión antiguo del almacenamiento, reforzando la protección contra accesos no autorizados.

Además, es recomendable controlar la propagación del ID de sesión evitando incluirlo en URLs o formularios. La configuración debe asegurarse de que el ID de sesión se transmita únicamente mediante cookies seguras.

Configuración adicional para reforzar la seguridad de la sesión:

<?php
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'domain' => 'tudominio.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict',
]);

session_start();

// Tras autenticación exitosa
if ($autenticado) {
    session_regenerate_id(true);
    $_SESSION['usuario'] = $usuario;

    echo "Sesión iniciada correctamente\n";
} else {
    echo "Error en la autenticación\n";
}

En este ejemplo, se establecen parámetros de cookie segura antes de iniciar la sesión, y luego se regenera el ID tras la autenticación. Esto combina varias medidas de seguridad para proteger la sesión del usuario.

Es fundamental que la regeneración del ID de sesión se realice después de verificar las credenciales y antes de establecer cualquier información sensible en $_SESSION. De esta manera, se evita que un atacante pueda aprovechar un ID de sesión antiguo para acceder a recursos restringidos.

Resumen de buenas prácticas al regenerar el ID de sesión:

  • Siempre llamar a session_regenerate_id(true) tras un inicio de sesión exitoso.
  • Asegurarse de que el ID anterior se invalide utilizando el parámetro true.
  • Configurar las cookies de sesión con atributos Secure, HTTPOnly y SameSite.
  • No exponer el ID de sesión en URLs ni campos de formularios.

Implementar estas medidas aumenta significativamente la seguridad de las sesiones en aplicaciones PHP, protegiendo tanto al usuario como al sistema de posibles ataques.

Manejo de tiempos de expiración y cierre de sesión seguro

El manejo adecuado de los tiempos de expiración en las sesiones y su cierre seguro es esencial para proteger aplicaciones web y mantener la confidencialidad de los datos de los usuarios. Configurar correctamente la duración de las sesiones ayuda a prevenir accesos no autorizados y reduce el riesgo de que sesiones inactivas sean aprovechadas por terceros malintencionados.

Para establecer el tiempo de vida máxima de las sesiones en PHP, se utiliza el parámetro session.gc_maxlifetime, que define en segundos cuánto tiempo debe conservarse una sesión antes de ser eliminada por el recolector de basura. Se puede configurar en el archivo php.ini o dinámicamente con ini_set:

<?php
ini_set('session.gc_maxlifetime', 1800); // 30 minutos
session_start();

En este ejemplo, las sesiones expirarán después de 1800 segundos de inactividad. Es importante coordinar este valor con el tiempo de vida de la cookie de sesión para asegurar una consistencia entre el servidor y el cliente.

Para controlar la duración de la cookie de sesión en el navegador del usuario, se utiliza session_set_cookie_params(). Esto define cuánto tiempo el navegador debe conservar la cookie antes de eliminarla:

<?php
session_set_cookie_params([
    'lifetime' => 1800, // 30 minutos
    'path' => '/',
    'domain' => 'tudominio.com',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict',
]);
session_start();

Al establecer 'lifetime' => 1800, la cookie de sesión será válida durante 30 minutos. De esta manera, si el usuario permanece inactivo más allá de este periodo, la sesión expirará y deberá volver a autenticarse.

Implementar un sistema que gestione el tiempo de inactividad del usuario es una buena práctica de seguridad. Esto se puede lograr almacenando la marca de tiempo del último acceso y comparándola en cada solicitud:

<?php
session_start();

$tiempoInactividad = 600; // 10 minutos

if (isset($_SESSION['ultimo_acceso'])) {
    $inactivo = time() - $_SESSION['ultimo_acceso'];
    if ($inactivo > $tiempoInactividad) {
        // Cerrar sesión por inactividad
        session_unset();
        session_destroy();
        header("Location: login.php");
        exit();
    }
}

$_SESSION['ultimo_acceso'] = time();

En este código:

  • Se define un tiempo máximo de inactividad de 10 minutos.
  • Si el usuario supera este tiempo sin actividad, la sesión se cierra automáticamente.
  • Se actualiza 'ultimo_acceso' en cada interacción para reflejar la última actividad.

Es fundamental asegurar que al cerrar la sesión, esta se destruya de manera completa y segura. Para ello, se deben seguir estos pasos:

  1. Eliminar todas las variables de sesión con session_unset().
  2. Destruir la sesión con session_destroy().
  3. Eliminar la cookie de sesión del navegador.

Eliminar la cookie de sesión garantiza que el navegador no envíe un ID de sesión inválido al servidor. Esto se logra con:

<?php
session_start();
session_unset();
session_destroy();

// Eliminar la cookie de sesión en el cliente
if (ini_get('session.use_cookies')) {
    $parametros = session_get_cookie_params();
    setcookie(session_name(), '', [
        'expires' => time() - 42000,
        'path' => $parametros['path'],
        'domain' => $parametros['domain'],
        'secure' => $parametros['secure'],
        'httponly' => $parametros['httponly'],
        'samesite' => $parametros['samesite'] ?? 'Lax',
    ]);
}

Este proceso asegura que la sesión se elimina tanto del servidor como del cliente, evitando posibles reutilizaciones del ID de sesión por parte de un atacante.

Para aumentar la protección contra el secuestro de sesiones, es recomendable verificar información adicional del usuario, como la dirección IP o el agente de usuario. Por ejemplo, comprobando la IP en cada solicitud:

<?php
session_start();

// Al iniciar sesión, almacenar la IP del usuario
if (!isset($_SESSION['ip_usuario'])) {
    $_SESSION['ip_usuario'] = $_SERVER['REMOTE_ADDR'];
} elseif ($_SESSION['ip_usuario'] !== $_SERVER['REMOTE_ADDR']) {
    // Si la IP cambia, cerrar la sesión
    session_unset();
    session_destroy();
    header("Location: login.php");
    exit();
}

Aquí, si la dirección IP del usuario cambia durante la sesión, esta se finaliza para prevenir accesos no autorizados desde otra ubicación.

Es importante informar a los usuarios sobre el tiempo de expiración de sus sesiones y proporcionar avisos antes de que se cierre la sesión por inactividad. Esto mejora la usabilidad y permite al usuario extender su sesión si lo desea.

Además, se pueden implementar técnicas como la regeneración periódica del ID de sesión durante la sesión activa, lo cual añade una capa extra de seguridad. Esto se realiza utilizando session_regenerate_id() en intervalos definidos.

Finalmente, establecer políticas claras de cierre de sesión y tiempos de expiración contribuye a mantener la integridad y seguridad de la aplicación. Revisar y actualizar regularmente estas configuraciones es esencial para adaptarse a nuevas amenazas y mantener un entorno seguro.

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

  1. Entender la importancia de la seguridad en el manejo de cookies.
  2. Configurar cookies usando atributos HTTPOnly y Secure en PHP.
  3. Prevenir ataques de Cross-Site Scripting (XSS).
  4. Evitar el envío de cookies por conexiones no cifradas.
  5. Implementar el atributo SameSite para proteger frente a CSRF.
  6. Regenerar el ID de sesión tras el inicio de sesión para prevenir fijación de sesión.
  7. Configurar tiempos de expiración adecuados para sesiones y cookies.
  8. Destruir sesiones de forma segura para evitar la reutilización por atacantes.