1

我有一个用于测试我的编程方法的基本站点,我想获得一种让人们保持登录状态的半体面的安全方式。这是register.php.

$username = $_POST["username"]; //username stored plaintext
$passhashed = crypt($_POST["password"], $username); //hashed password salted with username
$rnum = rand(1000,9999); //assign random 4-digit number
$authkey = crypt($rnum, $passhashed); //unique authentication key per user, hashed and salted with hashed password
//insert into SQL

当他们登录时$username$passhashed、 和$authkey存储在$_SESSION数据中。

在每一页的顶部,我都有以下代码片段:

if(isset($_SESSION["username"])
&& isset($_SESSION["password"])
&& isset($_SESSION["authkey"])) {
    $verifyuser = $db->prepare("
        SELECT *
            FROM users
            WHERE username = :user
            AND password = :password
            AND authkey = :authkey
    ");
    $verifyuser->execute(array(
        ':user' => $_SESSION["username"],
        ':password' => $_SESSION["password"],
        ':authkey' => $_SESSION["authkey"]));
    if($verifyuser->rowCount() != 1) {
        unset($_SESSION["username"]);
        unset($_SESSION["password"]);
        unset($_SESSION["authkey"]);
    }
}

基本上在任何给定的页面上,它都会执行一个检查,以检查每个存储的片段$_SESSION是否使用 SQL 清除,如果没有(如果任何检查失败,将给出rowCount非 1),它会丢弃会话。

我将是第一个承认我对逃避会话劫持的当代安全措施不太熟悉的人(事实上,我对它是如何完成的只有一个松散的控制)。话虽这么说,这对于初学者程序员来说如何?我可以做些什么来使其更安全?在登录时分配第二个身份验证密钥,将其临时存储在 SQL 中并进行相同的检查(每次登录新密钥)?

4

2 回答 2

2

crypt功能有些过时了。你最好使用 bcrypt,它是在 PHP 中使用password_hash和提供的password_verify。此外,使用这些函数,盐(您所称$authkey的)被集成到字符串中,因此您不需要单独存储它。

我注意到您将用户名和密码存储在$_SESSION. $_SESSION客户端不能直接修改,因此最好将用户的 ID 存储在那里。

于 2013-09-22T23:22:47.420 回答
2

正如您所提到的,我对会话劫持也有基本的了解。

但是我认为如果这 3 个被劫持,这仍然可能无法阻止帐户劫持,尽管确实使劫持变得更加困难。

在阅读防止会话劫持时,我看到了一个简单的示例 - 如果当前 IP 与会话不匹配,则将用户注销。

<?php
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR'])
{
session_destroy();
}
?>

典型:我再也找不到所说的网站...

一些可能对您有所帮助的链接:

防止会话劫持

PHP中正确的会话劫持预防

于 2013-09-22T23:29:23.800 回答