Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusConfiguració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
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
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:
- Eliminar todas las variables de sesión con
session_unset()
. - Destruir la sesión con
session_destroy()
. - 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.
Aprendizajes de esta lección de PHP
- Entender la importancia de la seguridad en el manejo de cookies.
- Configurar cookies usando atributos HTTPOnly y Secure en PHP.
- Prevenir ataques de Cross-Site Scripting (XSS).
- Evitar el envío de cookies por conexiones no cifradas.
- Implementar el atributo SameSite para proteger frente a CSRF.
- Regenerar el ID de sesión tras el inicio de sesión para prevenir fijación de sesión.
- Configurar tiempos de expiración adecuados para sesiones y cookies.
- Destruir sesiones de forma segura para evitar la reutilización por atacantes.
Completa este curso de PHP y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs