Autor Zpráva
koudelacek
Profil *
Dobrý den,
prošel jsem již několik článků o ochraně sessions, ale pořád jim moc nerozumím, proto bych byl rád, kdyby mi někdo poslal nějaký pochopitelný návod jak chránit sessions a jak vylepšit můj kód.

Při učení php jsem použil jednoduchý přihlašovací formulář z php učebnice:

/* KONTROLA PRIHLASOVACIH UDAJU */
function check_log($login, $password){
    $search=mysql_query('SELECT id FROM users WHERE nickname="'.mysql_real_escape_string($login).'" and password="'.mysql_real_escape_string($password).'" and active="1"', $GLOBALS['connect']);
    $res=@(mysql_fetch_array($search));
    return $res['id'];
    } 

/* PRIHLASOVACI FORMULAR */
function log_form(){
unset($_SESSION["id"]);
echo '
  <form method="post" action="'.$_SERVER["REQUEST_URI"].'">
  <table class="form">
    <tr>
      <td class="bold">Přihlašovací jméno:</td>
      <td><input name="login"></td>
    </tr>
    <tr>
      <td class="bold">Heslo:</td>
      <td><input name="password" type = "password"></td>
    </tr>
    <tr>
      <td colspan="2"><input class="submit" type="Submit" name="Send" value=""></td>
    </tr>
  </table>
  </form>
  <p><a href="'._indexroot.'lost_password.php">Zapomněl jsem heslo.</a><br /><a href="'._indexroot.'registration.php?s=1">Chci se zaregistrovat.</a></p>';};

echo '<h2>Přihlášení</h2>
<br />
<div id="content">';
if(@($_SESSION["id"]))
  {
  echo '<script type="text/javascript">window.location = "'._indexroot.'"</script>'; 
  }      
  else
  {
      if(!empty($_POST))
          {
          if(check_log($_POST['login'], md5($_POST['password'])))
              { 
              $_SESSION["id"]=check_log($_POST['login'], md5($_POST['password']));
              if(@($_SESSION["id"]))
                  {
                  echo '<script type="text/javascript">window.location = "'._indexroot.'"</script>';
                  }
              else
                  {
                  echo 'Přihlášení neproběhlo. Zkuste to, prosím, znovu.';
                  }
              }
          else
              {        
              echo '<p class="error3 pad5">Vaše přihlašovací jméno nebo heslo nesouhlasí nebo jste zatím nedokončili registraci! <br />';
              echo 'Pokud jste zapomněli heslo, nechte si <a href="'._indexroot.'lost_password.php">zaslat nové</a>.</p>';
              log_form();
              }
          } 
      else 
          {
          log_form();
          }     
  }

Děkuji za každou radu.
Str4wberry
Profil
Když to shrnu, tak je vhodné zejména
1) session nepředávat v URL (používat je jen přes cookies),
2) mít jako Session ID hodnotu, kterou ze strany útočníka nelze jednoduše odvodit,
3) nemít na webu jiné bezpečnostní díry.
ShiraNai7
Profil
Pro další stupeň ochrany je také možné session vázat na konkrétní IP adresu (ukládat IP při přihlášení a poté ji kontrolovat). Ale je dobré, aby to bylo volitelné, protože bývají uživatelé s připojením které může IP adresu měnit častěji než je doba aktivity na stránce (docházelo by pak k odhlašování).
koudelacek
Profil *
Takže to co jsem poslal nějak vadné není, stačí více zakódovat to ID ? Např pomocí md5 ?


A ještě - když jsem doteď použival to id jakožto id uživatelů do některých odkazů, jak to potom mám nahradit ?
Nox
Profil
SESSION ID != Session['ID'] <--- konkrétní jedna hodnota v Session
\--- identifikátor Sessiony

jinak ohledně Session a bezpečnosti je toho hodně na Wiki, včetně řešení
koudelacek
Profil *
Je dobré dát session_regenerate_id() hned za sessions_start(), které mám v config.php - který includuju do každého souboru ?
Viděl jsem, že se mi pak ve složce se sessions čím dál víc hemžily..
ShiraNai7
Profil
To bych nedělal. Ale pokud chceš, tak alespoň nastav první argument této funkce na true. Soubory se pak množit nebudou.
session_regenerate_id(true);
koudelacek
Profil *
Jsou toto bezpečné SID ?

sess_da144e755021f3559bfb905c134fb25d
sess_7d45e27593bc2e806df17ec2ff3875fd
sess_5fc35008c0773a889e5681740c201428


Dobře, tak to tam dávat nebudu, ale četl jsem, že se to má umisťovat do přihlašovacího formuláře proti S Fixation, můžeš mi poradit kam do mého kódu ?
ShiraNai7
Profil
koudelacek:
Měly by být bezpečné. Ten hash může teoreticky nabýt nějakých 63,340,286,662,973,276,904,018,768,749,012,366,609,829,142,200,320 unikátních hodnot, ale záleží na konfiguraci PHP. V každém případě ID session uhádneš těžko. Taky si můžeš ID generovat sám, funkcí session_id()

Spoj to s volitelnou vazbou na IP adresu a bude to podle mě dostatečně bezpečné.
koudelacek
Profil *
A ta regenerace id ? Mám to správně ?

          if(check_log($_POST['login'], md5($_POST['password'])))
              { 
              session_regenerate_id();
              $_SESSION["id"]=check_log($_POST['login'], md5($_POST['password']));
              if(@($_SESSION["id"]))
                  {
                  echo '<script type="text/javascript">window.location = "'._indexroot.'"</script>';
                  }
              else
                  {
                  echo 'Přihlášení neproběhlo. Zkuste to, prosím, znovu.';
                  }
              }
ShiraNai7
Profil
Zběžně ano.. ale doplň parametr true pro funkci session_regenerate_id() na řádku 3. Na serveru pak nezůstanou zbytečná data session, které se stejně pak nebudou používat:

session_regenerate_id(true);
Alphard
Profil
Konstrukce v [#10] je dost špatně čitelná.
Funkci session_regenerate_id() bych takto nepodmiňoval a dal do kódu po přihlášení a odhlášení, je obvyklé ji volat po změně oprávnění uživatele, při každém požadavku se většinou nevolá.

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: