我简单的用户身份验证系统是否足够安全?

时间:2018-08-20 10:42:51

标签: php security session authentication cookies

我一直在开发用于用户登录的身份验证系统,希望能得到一些反馈。

我的想法是这样。使用会话和一个额外的cookie。会话cookie和其他cookie一起工作。在我的登录类中,检查用户名和密码是否正确后,我调用 sessionStart 方法并从数据库发送用户ID:

public function sessionStart($id) {
    session_start();
    $cookieName = "RagingBull";
    $hash = $this->loginHash($id);
    setcookie($cookieName, $hash);
}

在我的sessionStart方法中,调用了一个 loginHash 方法。 loginHash方法创建哈希并将会话cookie和其他cookie链接在一起。

public function loginHash($id) {
    $timeStamp              = time();
    $randNumber             = mt_rand(0, 1000);
    $userId                 = $id;
    $_SESSION['timeStamp']  = $timeStamp;
    $_SESSION['randNumber'] = $randNumber;
    $_SESSION['userId']     = $id;
    $userAgent              = $_SERVER['HTTP_USER_AGENT'];
    $salt                   = "On the Waterfront";
    $ipFrag                 = substr($this->getUserIP(), 0, 5);
    $forHash                = $timeStamp.$salt.$userId.$ipFrag.$randNumber.$userAgent;
    $hash                   = md5($forHash);
    return $hash;

}

为了创建哈希值,我使用

  • timeStamp,它也保存在会话cookie中
  • randNumber,保存在会话cookie中
  • userId,保存在会话cookie中
  • userAgent,
  • 盐,该盐内部保存在服务器上
  • ipFrag,只是用户IP地址的一部分。

我将一些值保存在会话cookie中,以便以后在创建哈希进行比较时可以使用它们。之后,我们返回sessionStart方法,并使用返回的哈希值创建其他cookie,然后用户登录。

对于身份验证,我具有 Session 类。

class Session {

public function __construct() {

    session_start();
    // checks to see if all the cookies are there
    if(!isset($_SESSION['userId']) || !isset($_COOKIE['RagingBull'])) {
        header("Location:http://localhost/login.php");
    }

    //create hash for comparison
    $hash = $this->loginHash();

    //if hashes are not the same, redirect
    if(strcmp($hash, $_COOKIE['RagingBull']) !== 0) {
        header("Location:http://localhost/login.php");
    }
}

public function loginHash() {
    $timeStamp  = $_SESSION['timeStamp'];
    $randNumber = $_SESSION['randNumber'];
    $userId         = $_SESSION['userId'];
    $userAgent  = $_SERVER['HTTP_USER_AGENT'];
    $salt       = "On the Waterfront";
    $ipFrag     = substr($this->getUserIP(), 0, 5);
    $forHash    =  $timeStamp.$salt.$userId.$ipFrag.$randNumber.$userAgent;
    $hash       = md5($forHash);
    return $hash;
}

public function getUserIP() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    return $ip;
}

}

要使用它,我只是创建Session类的实例。然后,在构造函数中,经过基本检查之后,创建了用于比较的哈希,我使用了之前保存的会话cookie中的timeStamp,userId和randNumber,并将它们与用户代理和来自请求页面的用户的ip片段组合在一起。

  • 是否存在明显的安全性或逻辑缺陷?
  • 它足够安全吗?
  • 对于每个页面请求,服务器是否要做太多工作?
  • 这是不必要的吗?

1 个答案:

答案 0 :(得分:0)

这段代码不安全地做了很多毫无意义的事情。

  • 使用mt_rand()代替random_int()
  • 使用md5($var)代替hash('sha256', $var)
  • 使用md5($password)代替password_hash()password_verify()
  • “登录哈希”完全没有意义。

如果您要进行持久身份验证(即“记住我” cookie),请just implement that

如果您要防止会话攻击,只需使用TLS(如果您仍使用PHP 5,并确保从/dev/urandom生成会话ID)和严格模式。每当用户登录或注销时,调用session_regenerate_id(true)。完成。

此处的哈希值没有任何价值,您使用的工具本来不是用于安全身份验证的。