Autor Zpráva
Jan Fabo
Profil *
Zdravim,

chcem sa spytat, kolko trva nez session_regenerate_id obnovi session aj s jej premennymi? ked testujem svoj aplikaciu a klikam dostatocne rychlo na odkazy, pricom pri kazdom pristupe sa vola session_regenerate_id(), tak obcas ma odhlasi s tym, ze nie su zaregistrovane premenne v ramci session.
ne ofic strankach sa o nicom takom nehovori, tak ma zaujima ci to nie je len bug u mna, alebo sa to da osetrit?

dik za radu. Jan Fabo
bohyn
Profil
Jan Fabo
kolko trva nez session_regenerate_id obnovi session aj s jej premennymi?
Neobnovuje, pouze prejmenuje. Sessions hodnoty jsou normale dale dostupne.

pri kazdom pristupe sa vola session_regenerate_id()
Ceho tim chces dosahnout?

obcas ma odhlasi s tym, ze nie su zaregistrovane premenne v ramci session.
Zda se, ze vseho moc skodi.
Jan Fabo
Profil *
dik za promptnu odpoved. kdesi na inete som cital o bezpecnejsom syteme s pouzitim tokenov, kde sa pri kazdom pristupe k aplikacii vygeneruje novy token. tak som si to iba zjednodusil a a pri kazdom pristupe si vygenerujem novy session id, ktory ulozim do db. pri dalsom pristupe potom porovnavam prijate sessionid s tym v db. ak sa zhoduju, vygenerujem nove id a aplikacia pokracuje dalej. ak sa nezhoduju -> login.php. chcem tak zabranit ukradnutiu session inym userom/utocnikom. a dalsi, podstatnejsi problem: mam dve aplikacie s rovnakym systemom prihlasovania, ale kazdy je samostatny. funguje tak, ze pri prihlaseni sa do session zaregistruje uid usera. no ale ma to velku nevyhodu, ze staci prepisat url na druhu aplikaciu a user je prihlaseny aj v nej.
lepsie bude ked postnem src:

funkcie
  function CheckSession(){
  // skontroluje ci je aktualna session_id rovna session_id z databazy
  // vrati true ak to sedi, inak false
    if ((isset($_SESSION[uid])) &&             // <- tato podmienka je nejakom 10x nevyhovie 
        (isset($_SESSION[guid])) &&           // coho vysledkom je premerovanie na login.php
        (isset($_SESSION[login]))){
    
      $UID = CheckInput($_SESSION[uid]);
      
      $datetime = explode(" ", date("Y-m-d H:i:s"));
      $date = explode("-",$datetime[0]);
      $time = explode(":",$datetime[1]);
      $last5min = date("Y-m-d H:i:s", mktime($time[0],$time[1]-5,$time[2],$date[1],$date[2],$date[0]));
      $sql = "select * from users
              where uid = $UID and
                    session_id = \"".session_id()."\" and 
                    posledny_pristup >= \"$last5min\"";
      $query = mysql_query($sql)
        or die("Chyba SQL"); 
      if (mysql_num_rows($query) > 0){
        // vsetko sedi, user je prihlaseny a session poslednych 5 min nevyprsala
        return true;
      }else{
        // nesedi sessionid v db a sessionid sucasnej session -> treba sa prihlasit
        return false; 
      }
    }else{
      // v ramci session nie je zaregistrovana ziadna z tychto premennych
      return false;
    }    
  }
  
  function RegenerateSession(){
  // vytvori nowe session id a zapise ho do db      
    session_regenerate_id();          
    $sql = "update users 
            set session_id =\"".session_id()."\",
                posledny_pristup = \"".date("Y-m-d H:i:s")."\"
            where uid = $_SESSION[uid]";
    $query = mysql_query($sql);
    if (!$query){
     // echo $sql;
     // exit;    
      return false;
    }else{
      return true;
    }     
  }


index.php
  session_start();

  require_once "functions.php";

  ConnectMySQL();
 
  if (!CheckSession()){
    echo "check sess"; 
   // exit;
    header("Location: login.php");
    exit;  
  }else{
    if (!RegenerateSession()){
      // nepodarilo sa regenerovat session id -> login.php
      echo "chyba regenerate sess";
      //exit;
      header("Location: login.php");
      exit;
    }
  }

  // html head.php, index.php


login.php
  session_start();
  
  // pripojenie na db
  require_once "functions.php";
    
  $ERROR = "";  
  $USERNAME = CheckInput($_POST[login]);
  $PASSWORD = CheckInput($_POST[passw]);  
    
  ConnectMySQL();
  if (CheckSession()){
    header("Location: index.php");
    exit;  
  }else{
    $SENT = CheckInput($_POST[sent]);
    if ($SENT){
      // prihlasovacie udaje boli prijate, nasleduje overenie v db 
      
      if (($USERNAME != "") && ($PASSWORD != "")){
        // prijate prihlasovacie udaje nie su prazdne retazce
        
        $sql = "select * from users 
                where login=\"$USERNAME\" 
                   and password=\"".md5($PASSWORD)."\"";
        $query = mysql_query($sql)
          or die("Chyba SQL");
        
        if (mysql_num_rows($query) > 0){
          $result = mysql_fetch_array($query);
          //session_destroy();
          
          $_SESSION[uid] = $result[uid];
          $_SESSION[guid] = $result[guid];
          $_SESSION[login] = $result[login];
                              
          // vytvorenie noveho session_id
          session_regenerate_id();
          
          // ulozenie session_id do db + aktualizacia posledneho pristupu usera
          $sql = "update users 
                  set session_id =\"".session_id()."\",
                      posledny_pristup = \"".date("Y-m-d H:i:s")."\"
                  where uid = $_SESSION[uid]";
          $query = mysql_query($sql)
            or die("Chyba SQL");

          header("Location: $posledna_akcia");
          exit;
        }else{
          $ERROR = "Takýto používateľ <br>neexistuje.";
        }
      }else{
        $ERROR = "Login ani heslo <br>nemôžu byť prázdne.";
      }
    }    
  } 

  // prihlasovaci formular


uff, dufam, ze sa to niekomu bude chciet citat :), neviem ako by som to jednoduchsie napisal...kazdopadne dakujem za kazdu radu. Jan Fabo
srigi
Profil
Osobne si myslim, ze ukladanie PHPSESSID (session_id() ) do databazy je zbytocnost. Zbytocne robis pocas obsluhy poziadavku niekolko SQL requestov. Uplne staci na ochranu pred session fixation pouzit volanie session_regenerate_id() hned po volani session_start(). Ihned po nastartovani session tak dojde k nastaveniu novej cookie, co je omnoho menej rezie ako nejake SQL overovanie.
bohyn
Profil
Jan Fabo
Cele jsem to necetl, ale pokud utocnik odchytne SID tak si vydeneruje nove SID a "odstrihne" tak prave prihlaseneho uzivatele => bezpecnost to neresi. Pouzivej misto toho kontrolu IP pripadne treba i user-agent.
Jan Fabo
Profil *
no dobre, mam takyto server:

https://server.sk/web/app1
https://server.sk/web/app2
- app1 a app2 su rozne aplikacie s roznymi uzivatelmi a pravami, ale s rovnakym sposobom prihlasovania - v ramci session sa zaregistruje premenna uid co je uid prihlaseneho usera

ked sa prihlasim na app1 a rucne prepisem URL na app2 tak som aj v tejto aplikacii prihlaseny, sice ako iny user, pretoze uid cisla su v kazdej app ine, ale som prihlaseny...napadlo ma, ze ked budem pre kazdu aplikaciu generovat nove session id a v kazdej z nich kontrolovat ci je rovnake, tak aspon tak odlisim userov jednej a druhej aplikacie.

co vy vlastne registrujete v session? ja som daval uid, ale ked uvazim, ze hocikto si moze zmenit cookie na uid administratora, tak to asi nebude velmi bezpecne...

Jan Fabo
Jan Fabo
Profil *
no dobre, mam takyto server:

https://server.sk/web/app1
https://server.sk/web/app2
- app1 a app2 su rozne aplikacie s roznymi uzivatelmi a pravami, ale s rovnakym sposobom prihlasovania - v ramci session sa zaregistruje premenna uid co je uid prihlaseneho usera

ked sa prihlasim na app1 a rucne prepisem URL na app2 tak som aj v tejto aplikacii prihlaseny, sice ako iny user, pretoze uid cisla su v kazdej app ine, ale som prihlaseny...napadlo ma, ze ked budem pre kazdu aplikaciu generovat nove session id a v kazdej z nich kontrolovat ci je rovnake, tak aspon tak odlisim userov jednej a druhej aplikacie.

co vy vlastne registrujete v session? ja som daval uid, ale ked uvazim, ze hocikto si moze zmenit cookie na uid administratora, tak to asi nebude velmi bezpecne...
Jan Fabo
Profil *
jaaaj, prepacte za duplicitu :(
bohyn
Profil
Jan Fabo
Napada me nekolik moznosti:
- Do session si ukladej jestli je to app1 nebo app2.
- pouzij session_set_cookie_params a nastav cestu v cookie pro kazdou aplikace, to ale neni bezpecne.
- Ulozit do session otisk hesla (treba sha1) a porovnavat s heslem v db

Edit:
- Pouzit stejnou databazi uzivatelu pro obe aplikace.
Jan Fabo
Profil *
presne - posledna moznost je najlepsia...akurat ze je s tym vela roboty a chcem to aspon docasne ochranit nez to urobim takto...
inak ono ten "moj sposob" by fungoval na toto co potrebujem celkom postacujuco, len keby sa mi z nejakeho zahadneho dovodu nestracali premenne v session...
Jan Fabo
Profil *
no uz som na to prisiel: ked som obnovil stranku rychlejsie ako sa stihol skoncit skript, tak to bolo kvoli tomu, ze session_regenerate_id blokuje staru session az do konca skriptu. takze premenne sa stracali preto, lebo server ich jednoducho lockol. urobil som toto:
    session_regenerate_id();
    $sid = session_id();
    session_write_close();
    session_id($sid);
    session_start(); 

a session premenne prechadzaju. teraz ale zapasim s tym skor ako sa mi server stihne poslat hociake data (teda aj cookie s novym session_id) dam obnovit stranku, ale toto obnovenie sa vykona este so starym session_id, ktore uz je neplatne...takze zase stuck... :(
Jan Fabo
Profil *
tak funguje to celkom spolahlivo, so session zaroven ukladam cas pristupu, ak je posledny pristup viac ako 5 min -> login.php. ak bude niekto klikat rychlejsie ako mu server stihne poslat nove cookie so session_id -> login.php. je to sice zataz na server z pohladu poctu vykonanych requestov ako hovoril srigi, ale v aplikacii nebude viac uzivatelov ako 20 a riesi to moj problem, aspon docasne. odchytenie session_id som utocnikom stazil pouzitim https. takze diki za pomoc.

no a stasne a vesele...a vela vody :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: