Terminología
- usuario: un visitante.
- Cliente: Un software particular con capacidad web instalado en una máquina en particular.
Sesiones Comprensión
Para entender cómo hacer que su sesión segura, primero hay que entender cómo funcionan las sesiones.
Vamos a ver este pedazo de código:
session_start();
Tan pronto como se llama eso, PHP buscará una cookie llamada PHPSESSID
(por defecto). Si no se encuentra, se creará uno:
PHPSESSID=h8p6eoh3djplmnum2f696e4vq3
si se encuentra, se toma el valor de PHPSESSID
y luego carga la sesión correspondiente. Ese valor se llama session_id
.
Eso es lo único que el cliente sabrá. Todo lo que agregue a la variable de sesión permanece en el servidor y nunca se transfiere al cliente. Esa variable no cambia si cambia el contenido de $_SESSION
. Siempre permanece igual hasta que lo destruyas o se agote. Por lo tanto, es inútil intentar ofuscar el contenido $_SESSION
al mezclarlo o por otros medios ya que el cliente nunca recibe o envía esa información.
Entonces, en el caso de una nueva sesión, establecerá las variables:
$_SESSION['user'] = 'someuser';
El cliente nunca va a ver esa información.
El problema
un problema de seguridad puede surgir cuando un usuario malicioso roba la session_id
de otro usuario. Sin algún tipo de control, él será libre de hacerse pasar por ese usuario. Necesitamos encontrar una manera de identificar de manera única al cliente (no al usuario).
Una estrategia (la más efectiva) consiste en verificar si la IP del cliente que inició la sesión es la misma que la de la persona que la usa.
if(logging_in()) {
$_SESSION['user'] = 'someuser';
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}
// The Check on subsequent load
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
die('Session MAY have been hijacked');
}
El problema con esta estrategia es que si un cliente utiliza un equilibrador de carga, o (en la sesión de larga duración) el usuario tiene una dirección IP dinámica, se disparará una alarma falsa.
Otra estrategia consiste en comprobar el agente de usuario del cliente:
if(logging_in()) {
$_SESSION['user'] = 'someuser';
$_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
}
// The Check on subsequent load
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) {
die('Session MAY have been hijacked');
}
La desventaja de esta estrategia es que si las actualizaciones de cliente que es navegador o instala un complemento (algunos se suma a la de agente de usuario), la cadena de agente de usuario cambiará y activará una alerta falsa.
Otra estrategia es rotar el session_id
en cada 5 solicitudes. De esta forma, el session_id
teóricamente no permanece el tiempo suficiente para ser secuestrado.
if(logging_in()) {
$_SESSION['user'] = 'someuser';
$_SESSION['count'] = 5;
}
// The Check on subsequent load
if(($_SESSION['count'] -= 1) == 0) {
session_regenerate_id();
$_SESSION['count'] = 5;
}
Puede combinar cada una de estas estrategias como lo desee, pero también combinará las desventajas.
Lamentablemente, ninguna solución es infalible. Si su session_id
está comprometido, está prácticamente acabado. Las estrategias anteriores son solo medidas para detenerse.
Cool. Creo que su método funciona mejor, no hay dudas al respecto. ¿Qué pasa si, combino el cheque, primero compruebo si el usuario inició sesión, verifico si el IP coincide con el IP de la sesión y verifico si el agente de usuario coincide con el agente de usuario de la sesión? ¿Es inútil? Solo necesito usar 1 de ella issit ?? – bbtang
BTW, basado en la respuesta koen. Parece que session_regenerate_id() es otra buena cosa, ¿eh? ¿Puedo hacerlo de esta manera, después de que el usuario haya iniciado sesión, session_start() y luego llame a sessio_regenerate_id() ?? ¿Es bueno o es inútil (solo cosas extra)? – bbtang
** @ bbtang: ** La combinación de ambos métodos también combinará sus desventajas. Puedes hacerlo a tu discreción. –