Una forma segura de manejar las sesiones en PHP
Eduardo Martes 13 de Febrero del 2007
Cuando entran a una página como al mail, sin que ustedes se den cuenta se genera automáticamente una variable de sesión, la cual sirve para identificar que una sesión esta activa, hay formas de verificar que una sesión esta activa, y con esto el servidor te da acceso o lo rechaza, una sesión no es mas que una cookie que expira en el momento que cierras el navegador.
Cada que entras a alguna página lo que valida la sesión es el servidor, asi que para que lo haga el navegador, envía las cookies pertenecientes a ese dominio al servidor, y con ésto puede identificarte.
Una cookie se puede falsificar, es un archivo en tu computadora que sera enviado al servidor, lo que se hace para falsificarlas es enviar una peticion http a un servidor, como se hace esto? un ejemplo es abrir la terminal en unix o linux o mac, y conectarte al puerto 80 de alguna pagina por ejemplo:
telnet 127.0.0.1 80
Y al hacer esto antes de recibir nada deberias enviar el http request por ejemplo:
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
POST /archivo.php HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/msword, */*
Referer: http://www.misitiodeprueba.com
Accept-Language: es
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; T312461)
Host: www.misitiodeprueba.com
Content-Length: 31
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: PHPSESIDQGGQGXSG=PBGKFHMDFHPDFHPIPLAHLDHL
login=usuario&pwd=password&modo=Entrar
(2 retornos de carro)
Ésto lo explico para que al hacer las validaciones piensen en que es posible falsificarlas, no voy a explicar a detalle como es que se falsifican, tal vez en otro post lo haga, pero la idea es intentar hacer más dificil todo ésto.
Una forma de hacer una validacion en php es de la siguiente forma para iniciar la sesión:
session_start();
//aqui nos conectamos a la base de datos
if(!empty($_SESSION['usuario'])) {
header("Location: inicio.php");
exit;
}
if($_POST && !empty($_POST['usuario']) &&
!empty($_POST['password']) ) {
//quitamos el posible SQLInjection del usuario
$_POST['usuario'] = mysql_real_escape_string($_POST['usuario']);
//sacamos el hash del password para que se compare ya encriptado
$_POST['password'] = md5(mysql_real_escape_string($_POST['password']));
//vemos si existen registros que coincidan
$query = mysql_query("SELECT * FROM usuarios ".
"WHERE usuario = '{$_POST['usuario']}' AND ".
"MD5(password) = '{$_POST['password']}' ");
if(mysql_num_rows($query) == 1) {
$_SESSION['usuario'] = $_POST['usuario'];
//generamos un token aleatorio para el usuario
$_SESSION['token'] = md5(rand().$_SESSION['usuario']);
//actualizamos el token para qu sean iguales el de la db
//y el de la sesión
mysql_query("UPDATE usuarios SET ".
"token = '{$_SESSION['token']}' WHERE ".
"usuario = '{$_SESSION['usuario']}' ");
//todo bien
header("Location: inicio.php");
exit;
} else {
session_destroy();
//usuario incorrecto o password incorrecto
}
mysql_free_result($query);
}
Y al cada que entre a una página, el php que lo recibe tendría un archivo incluido con más o menos lo siguiente:
session_start();
//aqui se debe de conectar a la base de datos y todo
//la función para validar la sesion sería algo asi:
function CheckNivel() {
if(!empty($_SESSION['usuario']) && !empty($_SESSION['token'])) {
//quitamos el posible SQLInjection del user y password
$_SESSION['usuario'] = mysql_real_escape_string($_SESSION['usuario']);
$_SESSION['token'] = mysql_real_escape_string($_SESSION['token']);
//checamos que exista
$query = mysql_query("SELECT * FROM usuarios ".
"WHERE usuario = '{$_SESSION['usuario']}' AND ".
"token = '{$_SESSION['token']}' ");
if(mysql_num_rows($query) == 1) {
//volvemos a calcular un token
$_SESSION['token'] = md5(rand().$_SESSION['usuario']);
mysql_query("UPDATE usuarios SET ".
"token = '{$_SESSION['token']}' WHERE ".
"usuario = '{$_SESSION['usuario']}' ");
} else {
session_destroy();
header("Location:login.php");
exit;
}
mysql_free_result($query);
}
}
Con ésto cada que refrescara la página o entrara a otra se cambiaría el id de sesión y nótese que en el id de sesión nunca se guarda el password, esa validación debe ser cuando entren al login, también dense cuenta que debemos usar mysql_real_escape_string($_SESSION['usuario']); para evitar SQLInjection y núnca guarden el password ni siquiera encriptado en la sesión, ya queda en cada uno de ustedes como quieran generar el token.
Asegurense que pongan como un require_once el archivo mencionado arriba, para que en caso de error envíe un error fatal y no siga ejecutando nada, pues si lo ponen como include en caso de un error del php dejaría ver la página simplemente mostrando una alerta.
Ésta apenas es una idea, también podrían checar la ip que siempre fuera la misma, o podrían hacer todo lo que les viniera a la mente, pero de ésta manera sería más seguro, quien quiera utilizar éste código es libre de hacerlo.






hola, mi pregunta sobre inicio de sesion pero desde windows, y al abrir un browser con una pagina creada en php ya reconosca al usuario que inicio desde windows.
de antemano un agradeciomiento si pueden contestar mi pregunta..
saludos