Foros del Web » Programando para Internet » PHP »

Cómo reforzar mi código de sesiones

Estas en el tema de Cómo reforzar mi código de sesiones en el foro de PHP en Foros del Web. Hola, buenas tardes, Estoy trabajando con sesiones PHP . Me basé en algunas guías, creando sesiones sencillas y poco a poco ir reforzándolas para que ...
  #1 (permalink)  
Antiguo 25/02/2014, 17:24
Avatar de Middrel  
Fecha de Ingreso: abril-2005
Mensajes: 835
Antigüedad: 19 años, 6 meses
Puntos: 27
Cómo reforzar mi código de sesiones

Hola, buenas tardes,

Estoy trabajando con sesiones PHP. Me basé en algunas guías, creando sesiones sencillas y poco a poco ir reforzándolas para que el ingreso sea más seguro. quería ver si me pueden ayudar con esto. En principio, coloco mi código de inicio de sesión y en base a este ir trabajando más en la seguridad.

Tengo mi archivo session.php, el cuál recibe los datos desde un formulario:

Código PHP:
    session_start();
    
    include(
"bd/config-sistema.php");
    include(
"reglas/mensajes.php");    
    
    
date_default_timezone_set('America/Mexico_City');
    
    if(isset(
$_POST['enviar'])){
        
$diaActual date("Y-m-d");
        
        
// Utilizamos mysql_real_escape_string para evitar SQL Injection -> Filtro 1
        
$user mysqli_real_escape_string($connect$_POST['user']);
        
$pass mysqli_real_escape_string($connect$_POST['pass']);
        
        
$passCodif crypt($pass'$2a$07$vasto78try14perma09wq2$');
        
        
// Buscamos que el usuario se encuentre en la base de datos y no tenga un máximo de 3 intentos de logueo -> Filtro 2    
        
$sqlSelectUser mysqli_query($connect"Select id_usuario, usu_usuario, usu_password, usu_baja, usu_bloqueo, usu_intentos, grp_grupo From sys_usuarios Left join sys_grupo On (id_grupo = usu_grupo) Where usu_usuario = '$user'"MYSQLI_USE_RESULT)  or die(mysqli_error($connect));
        
$rowSelectUser mysqli_fetch_array($sqlSelectUserMYSQLI_ASSOC);

        
$ide $rowSelectUser['id_usuario'];
        
$usuario $rowSelectUser['usu_usuario'];
        
$password $rowSelectUser['usu_password'];
        
$grupo $rowSelectUser['grp_grupo'];        
        
$vigencia $rowSelectUser['usu_baja'];
        
$bloqueo $rowSelectUser['usu_bloqueo'];    
        
$intentos $rowSelectUser['usu_intentos'];
        
        
mysqli_free_result($sqlSelectUser);        
        
        
// Revisamos que el usuario exista y sea el mismo al introducido
        
if($usuario == $user){ 
        
            
// Verificamos que no tenga algún bloqueo
            
if($bloqueo == 1){ 
            
                
$mensaje $bloqueoLogin
            
            
// Ahora verificamos que el password coincida con el almacenado
            
} elseif($password == $passCodif){ 
                
                
$_SESSION['estado'] = 'logueado';                // Definimos el estatus del usuario
                
$_SESSION['usuario'] = $ide;                    // Definimos el id del usuario
                
$_SESSION['registro'] = $usuario;                // Definimos el número de registro
                
$_SESSION['acceso'] = date('Y/m/d h:i:s A');    // Definimos la hora de entrada del usuario
                
$_SESSION['grupo'] = $grupo;                    // Definimos el grupo al que pertenece
                
$_SESSION['modulo'] = "";                        // Definimos el módulo al cuál acceso
                
$_SESSION['evento'] = "";                        // Definimos los movimientos que hizo el usuario
                
                
header('Location: empresa.php');    
            
            } else { 
            
                
// Si el usuario, realiza más de 3 intentos para ingresar con un password erróneo, la cuenta se bloqueará
                
if($intentos 3) {
                    
                    
$intentos $intentos 1;
                    
$sqlUpdateUsuarios mysqli_query($connect"Update sys_usuarios Set usu_intentos = $intentos Where id_usuario = $ide"MYSQLI_USE_RESULT) or die(mysqli_error($connect));
                    
                    
mysqli_free_result($sqlUpdateUsuarios);
                    
                    
$mensaje $passIncorrecto;    
                    
                } elseif (
$intentos == 3){
                    
                    
$fechaBloqueo strtotime('+1 day'strtotime($diaActual));
                    
$fechaDesbloqueo date("Y-m-d"$fechaBloqueo);
                    
                    
$sqlUpdateUsuarios mysqli_query($connect"Update sys_usuarios Set usu_bloqueo = 1 Where id_usuario = $ide"MYSQLI_USE_RESULT) or die(mysqli_error($connect));
                    
$sqlUpdateUsuarios mysqli_query($connect"Update sys_usuarios Set usu_fecha_desbloqueo = '$fechaDesbloqueo' Where id_usuario = $ide"MYSQLI_USE_RESULT) or die(mysqli_error($connect));                    
                    
                    
mysqli_free_result($sqlUpdateUsuarios);
                    
                    
$mensaje $bloqueoLogin;    
                }
            }
            
        } else {
            
            
$mensaje $errorInicio;
        }
    } 
Básicamente, ese es el inicio. Posteriormente en cada página, en el inicio añado el siguiente código:

empresa.php

Código PHP:
<?php include("sesiones/session.php"); if($_SESSION['estado'] != 'logueado'){ header('Location:index.php'); } ?>
en algunos casos, debido al grupo al que pertenezca el usuario existen secciones o módulos a los que no puede ingresar, eso lo realizo con esta instrucción:

Código PHP:
<div id="menu">
    <ul>
        <li class="menu"><a href="empresa.php">EMPRESA</a></li>
        <li class="menu"><a href="clientes.php">CLIENTES</a></li>        
        <li class="menu"><a href="facturacion.php">PEDIDOS</a></li> 
        <?php if($_SESSION['grupo'] == 'General' || $_SESSION['grupo'] == 'Administrativo'){ ?>       
        <li class="menu"><a href="#">COBRANZA</a></li>        
        <?php ?>
        <li class="menu"><a href="inventario.php">INVENTARIO</a></li>
        <?php if($_SESSION['grupo'] == 'General' || $_SESSION['grupo'] == 'Administrativo'){ ?>       
        <li class="menu"><a href="reportes.php">REPORTES</a></li>                
        <?php ?>        
    </ul>
</div>
existe un grupo de usuario que es el más bajo, o normal, este no podrá acceder a las opciones de Cobranza y Reportes. En el ejemplo de los menús, si se dan cuenta sólo muestro las opciones de acuerdo a la variable $_SESSION['grupo'], pero si el usuario sabe que existe una página llamada conranza.php y trata de escribirla en la barra de direcciones, agrego esta línea a esas páginas:

Código PHP:
<?php include("sesiones/session.php"); if($_SESSION['estado'] != 'logueado'){ header('Location:index.php'); } if($_SESSION['grupo'] != 'General'){ header('Location:modulo-restringido.php'); } ?>
y esto es lo que tengo. Leí que hay muchas formas de intentar entrar a un sitio mediante ataques, pero aún se me dificultan todos los métodos que puedo usar para que mi sitio sea seguro, por ejemplo, aún no implemento lo siguiente:

1. Evitar que un usuario entre con la misma cuenta de otro.
2. Finalizar la sesión cada cierto tiempo.
3. No sé si debo usar cookies o no.
4. Cerrar correctamente la sesión, para ello uso la siguiente sentencia:


destroy.php

Código PHP:
session_start();
    
session_destroy();
header('Location: ../index.php'); 
Bueno, ¿me podrían aconsejar si voy por buen camino?¿algo que se me esté pasando?¿si mi código es demasiado vulnerable?

De antemano, agradezco por sus comentarios. Toda crítica es bienvenida y asimilada como tal.

Saludos!!
  #2 (permalink)  
Antiguo 26/02/2014, 08:04
 
Fecha de Ingreso: junio-2011
Ubicación: Barcelona
Mensajes: 212
Antigüedad: 13 años, 5 meses
Puntos: 17
Respuesta: Cómo reforzar mi código de sesiones

Cita:
1. Evitar que un usuario entre con la misma cuenta de otro.
2. Finalizar la sesión cada cierto tiempo.
3. No sé si debo usar cookies o no.
Bueno lo primero es bastante complicado a no ser que por ejemplo recojas la IP del registrado y la ingreses en una tabla y verifiques si viene de esa misma IP. Aunque esto ultimo no te lo recomiendo para nada y ya no podra conectarse fuera de su casa, o smartphone, etc... Si lo que quieres es que una persona no utilice la cuenta del otro, esta casi imposible diria yo.

Lo segundo las sesiones ya finalizan solas de por si mismas al pasar x tiempo.

Lo tercero si usas sesiones yo diría que ya no hace falta.

Y lo cuarto yo utilizaria unset();.

Un saludo
__________________
Twitter: @ed33x
  #3 (permalink)  
Antiguo 26/02/2014, 09:26
Avatar de Middrel  
Fecha de Ingreso: abril-2005
Mensajes: 835
Antigüedad: 19 años, 6 meses
Puntos: 27
Respuesta: Cómo reforzar mi código de sesiones

Estaba pensando, y espero no complicarme más la existencia, cuando entre el usuario con su cuenta, en una tabla establecer un parámetro, por ejemplo:

tabla_estado
========
edo_id
edo_id_usuario
edo_estado


Al hacer login y pasar todos los filtros, configurar el estado a 1. Si cierra la sesión regresar el estado a 0. Si alguien quiere entrar con su cuenta y el estado es igual a 1, no permitirlo. Aunque no sé si esto sea lo correcto.

Por otro lado, voy a revisar unset() como me comentas.

Saludos! Gracias LiveTechno!!
  #4 (permalink)  
Antiguo 26/02/2014, 09:41
 
Fecha de Ingreso: junio-2011
Ubicación: Barcelona
Mensajes: 212
Antigüedad: 13 años, 5 meses
Puntos: 17
Respuesta: Cómo reforzar mi código de sesiones

El problema de lo que comentas es; ¿Y si deja la cuenta activa? Ponte el caso que cierra el navegador y no se da cuenta haya donde vaya no podrá iniciar sesión ya que el valor es 1.

Aunque una solución seria cada hora por ejemplo mediante cronjob que verifique desde la base de datos los valores de edo_estado y si es 1 que verifique si la (ejemplo) $_SESSION["usuario"] = $valorusuario_rand no existe que le cambie el valor a 0.

Un saludo!
__________________
Twitter: @ed33x
  #5 (permalink)  
Antiguo 26/02/2014, 09:57
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 12 años, 6 meses
Puntos: 320
Respuesta: Cómo reforzar mi código de sesiones

Cita:
1. Evitar que un usuario entre con la misma cuenta de otro.
Esto en si no es fácil de hacer, pero hay una solución muy buena que es la que implemento google con gmail. Esta implementacion hace que los puntos 2 y 3 que preguntas no sean necesarios.

La idea es la siguiente:
1-> Tener una tabla temporal en la bd de sessiones donde almacenas todos los datos del visitante (ip, dispositivo, sistema operativo, hora de logueo, ultimo_accesso, ultima_seccion_vista, ID_SESSION) el id_session sera el identificador de la session, o su nombre.
2-> Cuando un tipo accede a la web verificas si ya esta logueado, para eso verificas que la sesion exista y ademas, que esta sesion este en la tabla de la base de datos, si no esta, la eliminas y rediriges al login.
3-> Cuando el tipo se loguea, creas una sesion nueva, guardas los datos en la tabla de la base de datos y especificas que la sesion NO EXPIRE NUNCA (eso responde al punto 2) de esta forma el tipo quedara con el accesso activado hasta que se desloguee.
4-> Al hacer un logout destruyes la sesion y la borras de la bd.
5-> El usuario logueado debe de tener un panel donde ver desde donde esta logueado y poder desde alli, eliminar las sesiones. Con esto permites que el tipo se loguee desde su celular, su tablet, su notebook, su pc de escritorio, o desde una pc publica en simultaneo, si el tipo se olvida la cuenta abierta en una pc publica, o detecta que alguien ha ingresado (viendo las sesiones registradas) puede borrarlo inmediatamente, cambiar su contraseña y hasta enviarte una notificacion.

Ese es el sistema mas seguro y flexible que conozco, no obstante no es el unico y hay muchas tecnicas para lograr este efecto.

Dependiendo del servidor, podrias usar Memcache en lugar de una tabla en la base de datos, de esta forma si alguien ataca tu base de datos no obtendra ninguna info de las sesiones, aunque el consumo de ram crece de forma permanente junto con la cantidad de logins. Si tu sistema es en tiempo real, esta es la mejor opcion ya que es cientos de veces mas rapida que la anterior, pero si tu sistema es administrativo y por ende tiene poca interaccion (no hay chats, no hay intercambio de informacion constante) lo mejor es guardar en una base de datos para no saturar el servidor.


NOTA: Las sesiones usan cookies para propagarse, asi que usando sesiones, estás implícitamente usando cookies que almacenan el identificador de la session. (esto responde la duda 3)
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios
  #6 (permalink)  
Antiguo 26/02/2014, 10:11
Avatar de Middrel  
Fecha de Ingreso: abril-2005
Mensajes: 835
Antigüedad: 19 años, 6 meses
Puntos: 27
Respuesta: Cómo reforzar mi código de sesiones

Por lo que veo, hay muchos detalles a tomar en cuenta.

Voy a analizar todo lo que me comentan, les agradezco por la atención!!

Saludos!!!

Etiquetas: formulario, mysql, registro, select, sesiones, sql, usuarios, variable
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:33.