"Leak" by Session

Asked

Viewed 149 times

1

Something strange happened while we were using the system on the NET.

Well, every time a user logs into the system, I store his ID as follows:

$_SESSION['usuario']['uid'] = $id_user;

and direct you to index.php

header('location:index.php'); die();

Something happened, just once, that scared me.

The user CARLOS logged on to the system, and when JOÃO went to log in, typed user and password and entered as if it were CARLOS, and even stranger is that when the USER TAVAREZ typed the system IP, nor on the login screen he stopped, it was redirected directly to INDEX as CARLOS.

What can I do to prevent this kind of occurrence?

I am using PHP/Mysqli

As stated, below Authentication code:

if(isset($_POST["signup"])){

  $user = filter_var($_POST['matricula']);
  $senha = md5(filter_var($_POST['password']));
  $captcha = strtoupper($_POST['captcha']);

  if(!isset($_SESSION['captcha'])){
    $_SESSION['captcha'] = 123456;
  }

  if($_SESSION['captcha'] <> $captcha){ // Captcha não bate
    $_SESSION['erro'] = 'captcha';
  }

  else{ // verificação do captcha OK        
    unset($_SESSION['captcha']); // limpo a sessão

    if ($stmt = $mysqli->prepare("SELECT s.id_servidor, s.matricula, s.senha, s.fnome, s.alias, s.celular1, s.email, s.nascimento,s.id_status, s.id_perfil, s.foto, s.extensao, l.ultimo_acesso, l.tentativas, l.block, d.id_setor_real FROM tbl_servidores s, tbl_login l, tbl_dados_profissionais d WHERE s.id_servidor = l.id_servidor and s.id_servidor = d.id_servidor and s.matricula = ?")){
      $stmt->bind_param('s', $user);
      $stmt->execute();
      $stmt->store_result();

      if($stmt->num_rows == 1){ //Achei matricula no banco
        $stmt->bind_result($id_user, $matricula_user, $senha_user, $nome_user, $alias_user, $celular1_user, $email_user, $nascimento_user, $id_status_user, $id_perfil_user, $foto_user, $extensao_user, $ultimo_acesso_user, $tentativas, $block_user, $id_setor);
        $stmt->fetch();
        $stmt->close();

        if ($senha == $senha_user) {//senha OK

          if($block_user <> 's' and ($id_status_user == 1 or $id_status_user == 3) ){ // verifico se usuario não está bloqueado E status ativo.
            $_SESSION['usuario']['uid'] = $id_user; // gravo sessao

            if($ultimo_acesso_user =='0000-00-00 00:00:00'){//primeira vez
                $ultimo_acesso_user = date("Y/m/d H:i:s");  
            }

            $_SESSION['usuario']['ultimo_acesso'] = $ultimo_acesso_user;
            $_SESSION['tempolimite']=time()+$limite;

            if ($sqlupdate = $mysqli->prepare("UPDATE tbl_login SET ultimo_acesso = NOW(), registration_ip = '$ip', tentativas = 0, flag = 1 where id_servidor = '$id_user'")) {
            $sqlupdate->execute();
            $sqlupdate->close();
            }

            unset($_SESSION['contador']);
            unset($_SESSION['erro']);

            header('location:index.php'); die();// mando pro index
          }

          else{

            if($block_user == 's'){
             $_SESSION['erro'] = 'block';   
            }                       
            else{
             $_SESSION['erro'] = 'inativo';
            }
          }

       }//fim else senha == $senha_user

       else{ // errou a senha

         if($block_user == 'n'){
           $_SESSION['erro'] = 'erro_login';
           $qtde_tentativa = $tentativas + 1;

           if($qtde_tentativa == 10){
              $data = date("Y/m/d H:i:s");
              $chave = $id_user.$data;
              $hash = md5($chave);

              $sqlupdate = $mysqli->prepare("UPDATE tbl_login SET tentativas = 10, registration_ip = '$ip', block = 's' , hash_desbloqueio = '$hash' where id_servidor = '$id_user'");
              $sqlupdate->execute();
              $sqlupdate->close();

              //envia sms e/ou email
              $variavel_msg = 'bloqueado';
              date_default_timezone_set('Brazil/East');
              $final1 = date('dmy');
              $final2 = date('His');
              $id_serv_rem = $id_user;
              $id = $id_serv_rem.$final1.$final2;

              include ("mensagens/email.php");
              include ("mensagens/sms.php");
              $_SESSION['erro'] = 'block';

            }

            else{

              $sqlupdate = $mysqli->prepare("UPDATE tbl_login SET tentativas = '$qtde_tentativa' where id_servidor = '$id_user'");
              $sqlupdate->execute();
              $sqlupdate->close();

            }

          }

          else{
            $_SESSION['erro'] = 'block';
          }

        }

      }

      else{

       $_SESSION['erro'] = 'erro_login';

       if(!isset($_SESSION['contador'])){
         $_SESSION['contador'] = 0;
       }

       $_SESSION['contador'] = $_SESSION['contador'] + 1;
       $qtde_tentativa = $_SESSION['contador'];

       if($_SESSION['contador'] >= 3){
          unset($_SESSION['contador']);
          header('location:block_1.php'); die();

       }

    }

}

else{

  $_SESSION['erro'] = 'erro_sql';
}

}

}

  • 2

    How did you test that? The same browser?

  • So, 3 different computers. CARLOS logged in first, JOÃO second, TAVAREZ third. Important to know that this occurred only once, and then I still could not reproduce this error again.

  • No such thing has ever happened to me

  • 2

    Maybe the problem is the authentication code and not the code that handles the session.

  • Renan, the authentication code is simple, with the following logic: Else, error msg

  • I agree with @Renan, if possible put the Auth code.

  • @theteo Se achei a matrícula recupero a senha do banco With all due respect, I’ve seen this wheel reinvented several times. It is likely that your authentication code is perfect, but I have seen several times that the strategy of this type of query is wrong in every type of system. It is suggested to review this part of the code because it is a point that can fail.

  • I do not know if it would be the best solution, but try to check the ip and the user agent. so if each user accesses the different computer system, it will have different ip, forcing the user to log in.

  • I will edit the post with the Auth code

  • 2

    That code full of missing pieces isn’t gonna help much. It would be nice for the code in full (less passwords, of course) and preferably to format right. Looking like this you can already see that the logic is a little confused, but with the complete code can be easier to find which is the error that causes the specific problem you mentioned.

  • Okay, I’ll put the code in its entirety once I get to work.

  • I would not use session if I were you, or I would clear all sessions when logging in with a new user. The big problem with them is just this, from time to time PHP gets confused with some sesids and ends up accessing a session that is not what you want, even more if the system is networked and if users are accessing from the same machine.

  • @Khaosdoctor, at the beginning of the login.php page I have this: unset($_SESSION['user']); Exactly to clear the session.

  • There is no possibility of other sessions interfering?

  • session_name('radocs'); session_set_cookie_params('420'); session_start(); session_regenerate_id(); .

  • 1

    I have never seen this happen with PHP, are you sure you are always performing a new instance of the database statement and setting the authentication data? I believe that somehow PHP is doing "select" with old data, see if you have something similar

  • I did not understand why the password was validated outside the query and why you did not use LIMIT 1. Agree with @deFreitas should be something in the data returned by the query

Show 12 more comments
No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.