Достаточно ли безопасен этот код для сеанса PHP с «запомнить меня»? - PullRequest
1 голос
/ 06 ноября 2010

Я прочитал ОЧЕНЬ много информации о безопасности сеанса и придумал этот маленький кусочек кода.

Был бы признателен, если бы вы, ребята, взглянули на него и сказали мне, нужно ли мне что-то изменить насделать его лучше и безопаснее.

function cookie_auth(){
    if(isset($_COOKIE['cookie_name'])){
        $data = $_COOKIE['cookie_name'];
        list(,$username) = explode(':', $data);
        $sql = "SELECT * FROM tbl WHERE tbl.usrname= '$username'";
        $res = mysql_query($sql) or die(mysql_error());
        $row = mysql_fetch_array($res);
        $num_rows = mysql_num_rows($res);

        if ($num_rows==1){
            // AUTHENTICATE COOKIE VALUES
            $salt1 = sha1($row['alt_username']);
            $text = "constant_text_here";
            $salt2 = sha1($text);

            if($data == $salt1.':'.$username.':'.sha1($row['alt_username'].$salt2)){
                // USER IS AUTHENTICATED AND CORRECT
                $_SESSION['logged_in'] = true;
            }
        }

        else if ($num_rows!=1){
            // REDIRECT TO LOGIN PAGE
        }
    }//end if isset cookie

    // ELSE IF COOKIE ISN'T SET //
    else {
        // REDIRECT TO LOGIN PAGE
    }
}// end function cookie_auth //



// AUTHENTICATE USER //
if(!isset($_SESSION['logged_in']) || $_SESSION['logged_in']!==true){
        cookie_auth();
}

else if ($_SESSION['logged_in']===true){
    // FURTHER AUTHENTICATION //
    if($_SESSION['HTTP_USER_AGENT'] != sha1($_SERVER['HTTP_USER_AGENT']){
        header('Location: http://www.domain.com/login');
        session_destroy();
        die();
    }
}

Что вы думаете до сих пор?

Также кое-что, о чем я подумал:

Какой код следует использовать, еслипользователь не аутентифицирован?Должен ли я использовать "session_destroy", а затем "die ()"?Должен ли я использовать "unset session"?

Спасибо

Ответы [ 2 ]

1 голос
/ 06 ноября 2010
$data = $_COOKIE['cookie_name'];

Осторожно: $ _COOKIE ['cookie_name'] может быть массивом.По возможности используйте filter_input: $data = filter_input(INPUT_COOKIE, 'cookie_name');.

list(,$username) = explode(':', $data);

$ data не обязательно должен содержать :, поэтому проверьте, существует $ username или нет.

$sql = "SELECT * FROM tbl WHERE tbl.usrname= '$username'";

Высокий риск: уязвимость SQL-инъекции, вы всегда должны избегать ненадежных данных.Безопасный код:

$sql = sprintf("SELECT * FROM tbl WHERE tbl.usrname='%s'", mysql_real_escape_string($data));

Если состояние входа в систему изменяется (например, пользователь входит в систему), рекомендуется продолжить создание идентификатора сеанса перед продолжением.Это предотвратит фиксацию сессии.

0 голосов
/ 06 ноября 2010

Вы очень уязвимы для SQL-инъекций, я настоятельно рекомендую вам прочитать немного больше об этой теме и, возможно, переключиться на PDO, если ваш веб-хостинг поддерживает это. Лучший способ остановить SQL-инъекции в PHP

Существует также проблема с файлом cookie, который вы генерируете. Он содержит значения, которые не изменятся, если пользователь не изменит свой пароль. Это означает, что в случае, если злоумышленник получит чей-то cookie-файл, он сможет использовать его неограниченное время. Чтобы предотвратить использование того же файла cookie злоумышленником, можно добавить IP-адрес при создании файла cookie. Вероятно, лучший способ создать cookie-файл - использовать следующий код:

//I assume $row['alt_username'] is a secret key thing?
//It's best to change this value every login
$secretkey=$row['alt_username'];
//Best if your system supports the hash function with sha256
$hashed=hash("sha256", $secretkey."your_salt_here".$_SERVER['REMOTE_ADDR']);
//or else
$string=sha1($secretkey."your_salt_here".$_SERVER['REMOTE_ADDR']);

Кроме того, вы не хотите удваивать хэш, например, соль и имя пользователя, потому что это ограничит возможности хэша и значений имени пользователя (хотя это, вероятно, чисто теоретическая проблема, поскольку хэшировать не часто твоя соль).

...