这段代码对于“记住我”的PHP会话是否足够安全?

时间:2010-11-06 14:39:30

标签: php html security session browser

我已经阅读了大量有关会话安全性的信息,并提出了这段代码。

如果你们看一下它并告诉我是否需要改变一些东西以使它更好更安全,我将不胜感激。

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()”吗?我应该使用“未设置会话”吗?

由于

2 个答案:

答案 0 :(得分:1)

$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));

如果登录状态发生变化(例如用户登录),最好在继续之前重新生成会话ID。这将阻止会话固定。

答案 1 :(得分:0)

您非常容易受到SQL注入攻击,我强烈建议您阅读有关该主题的更多内容,如果您的网站主机支持此操作,可能会切换到PDO。 Best way to stop SQL injections in PHP

您正在生成的Cookie也存在问题。除非用户更改密码,否则它包含不会更改的值。这意味着在恶意用户获得某人cookie的情况下,他们将能够无限期地使用它。避免恶意用户使用相同cookie的方法可以是在cookie生成中添加IP地址。生成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']);

此外,您不希望加密哈希值,例如您的salt和用户名,因为这只会限制哈希值和用户名值的可能性(尽管这可能纯粹是一个理论问题,因为它不常用于哈希你的盐。)