【问题标题】:Three tiered security check; session still vulnerable?三层安全检查;会话仍然脆弱?
【发布时间】:2023-03-16 15:28:01
【问题描述】:

我有一个基本站点,我用它来测试我的编程方法,并且我想获得一种让人们保持登录状态的安全方式。这是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 数据中。

在每一页的顶部,我都有以下 sn-p 代码:

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 清除,如果没有(如果任何检查失败,将给出非 1 的rowCount),它会丢弃会话。

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

【问题讨论】:

  • 除非你经营一家银行,否则它可能就足够了
  • 我认为这并不重要,但 $_SESSION 的数据与 ini_set('session.cookie_lifetime', 60*60*24*3);ini_set('session.gc_maxlifetime', 60*60*24*3); 一起保存了几天。
  • 所以我是对的,通常 SESSION 不会存在。但这无论如何都行不通。用户回来时将获得一个新的会话 ID。

标签: php security session


【解决方案1】:

The crypt function 有点过时了。最好使用 bcrypt,它是在 PHP 中使用 password_hashpassword_verify 提供的。此外,使用这些函数,盐(你称之为$authkey)被集成到字符串中,所以你不需要单独存储它。

我注意到您将用户名和密码存储在 $_SESSION 中。 $_SESSION 不能被客户端直接修改,所以你最好把用户的 ID 保存在那里。

【讨论】:

  • 干杯。我一直在寻找更相关和更安全的散列方法。事实上,直到几天前,我才使用md5(),认为它甚至有一点安全性。谢谢!
【解决方案2】:

正如你所说,我对会话劫持也有基本的了解。

但是我认为,如果这 3 个被劫持,这仍然可能无法阻止帐户劫持,尽管确实会增加难度。

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

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

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

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

Preventing session hijacking

Proper session hijacking prevention in PHP

【讨论】:

  • 这实际上是一种非常简单但很好的做事方式。我已将其附加到我的代码中,谢谢!
  • 没问题 - 但请考虑我包含的链接上所说的内容 - 如果您还没有看过,因为 IP 更改背后可能有真正的原因。
  • 坏主意,ip!=person,可以在请求之间轻松合法地更改。
  • @Dagon,我认为重点是每次登录时都会分配$_SESSION['ip'];它只是确保在那个人——而且只有那个人——登录到他们的帐户时,会话保持活动状态。如果会话被劫持,它会在检测到会话中的 IP 与访问者的 IP 不匹配时立即丢弃。
  • ip 可以更改而不会被劫持
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 2018-06-30
相关资源
最近更新 更多