Autor Zpráva
czmarci
Profil *
Zdravím, chystám vlastní systém, který by měl být dostupný pouze přihlášeným uživatelům, protože bude obsahovat důvěrná data. Před jeho spuštěním bych chtěl požádat zdejší programátory o kontrolu mnou vytvořeného login skriptu (nechci přihlašování uživatelů podcenit).

login.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Přihlašte se prosím..</title>
    <link rel="stylesheet" type="text/css" href="./css/login.css" />
</head>
<body>
    <div class="login_form">
        <div class="padd20px">
            <form action="login_process.php" method="POST">
                <label>E-mail: </label>
                <input name="myusername" class="login_text" type="text" />
                <label>Heslo: </label>
                <input name="mypassword" class="login_text" type="password" />
                <input type="submit" class="login_submit" value="Přihlásit" /></td>
            </form>
        </div>
    </div>
</body>
</html>

login_process.php
připojeným config souborem se připojuje skript k mysql
<?php
ob_start();
session_start();
require_once("_config.php");

$myusername = $_POST['myusername']; 
$mypassword = $_POST['mypassword'];

$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);

$mypassword = md5($mypassword);

$sql    = "SELECT * FROM uzivatele WHERE jmeno='$myusername' and heslo='$mypassword'";
$result = mysql_query($sql);
$row    = mysql_fetch_assoc($result);

$count=mysql_num_rows($result);

if($count==1){
    $key  = $row['id'];
    $key .= $row['jmeno'];
    $key .= $_SERVER['REMOTE_ADDR'];
    $key .= "další část klíče, kterou nebudu zveřejněňovat";
    $key  = sha1(md5($key));
    $id   = $row['id'];
    
    session_register("key");
    session_register("id");
    
    if(!empty($_SESSION["key"]) || !empty($_SESSION["id"])) {
        $_SESSION["key"] = $key;
        $_SESSION["id"]  = $id;
    }
    
    header("Location: index.php?err=1");
    exit;
}
else {
    session_destroy();
    header("Location: login.php?err=0");
    exit;
}
ob_end_flush();
?>

login_verify.php
<?php
ob_start();
session_start();
if(empty($_SESSION["id"]) || empty($_SESSION["key"])) {
    session_destroy();
    header("Location: login.php?err=2");
    exit;
}
else {
    function verify_key() {
        require_once("_config.php");
        
        $id = $_SESSION["id"];
        $id = stripslashes($id);
        $id = mysql_real_escape_string($id);
        
        $sql    = "SELECT * FROM uzivatele WHERE id='$id'";
        $result = mysql_query($sql);
        $row    = mysql_fetch_assoc($result);
        
        $key  = $row['id'];
        $key .= $row['jmeno'];
        $key .= $_SERVER['REMOTE_ADDR'];
        $key .= date(".N.j.n.Y.z");
        $key  = sha1(md5($key));
        
        if($_SESSION["key"] != $key) {
            return false;
        }
        else {
            return true;
        }
    }
    
    if(verify_key() != true) {
        session_destroy();
        header("Location: login.php?err=2");
        exit;    
    }
    else {
        return;
    }
}
ob_end_flush();
?>

index.php
<?php require_once("login_verify.php"); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>Tajná stránka</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" type="text/css" href="./css/style.css" />
</head>
<body>
    Stránka, která se zobrazí přihlášeným uživatelům.<br />
    <a href="logout.php">Odhlásit se..</a>
</body>
</html>

logout.php
<?php
    session_start();
    session_destroy();
    header("Location: login.php?err=3");
?>


Všem děkuji za pomoc.
czmarci
Profil *
Ještě dodám že v login_verify.php se ověřuje i datum
 $key .= date(".N.j.n.Y.z");
to jsem nechtěně vymazal z login_process.php nad
$key .= "další část klíče, kterou nebudu zveřejněňovat";

Ta další část klíče je např. "blabla" nastavená v administraci systému.
mzk
Profil *
czmarci:
- to že to nechceš podcenit neznamená že musíš všude cpát mysql_real_escape_string, ne vždy to má smysl např.
$mypassword = mysql_real_escape_string($mypassword);
 
$mypassword = md5($mypassword);

- z databáze nemusíš tahat všechny data
- a dle mého názoru je sha1(md5($key)) taky blbost
- asi bych to neroztahoval na tolik souborů
czmarci
Profil *
mzk:
Díky za reakci.

V prvním případě jsem si neuvědomil, že hned za mysql_real_escape_string následuje MD5, takže sql injection snad nehrozí. Moje blbost ;)

Bezpečností klíč má bránit session stealingu i když jsem to s kombinací md5 a sha1 asi přehnal, bohatě by např. sha1 stačilo. Mě šlo o to, aby byl výsledný klíč nečitelný, pokud se nikomu podaří ukrást session s klíčem. Bohužel o session stealingu nevím téměř nic, proto jsem tak trochu paranoidní.

Data uložená v systému jsou velmi důvěrná, tak si nad přihlašování lámu hlavu. Nerad bych aby se data dostali do nepravých rukou.

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: