2

很明显,我们大多数 PHP 程序员不希望我们发布的作品以我们不希望的方式被黑客入侵或利用。因此,在询问如何应对会话劫持时,我会格外小心。我知道有 session_regenerate_id() 函数可以部分对抗会话劫持,但我对我遇到的另一种方法更好奇:

当用户登录网站时,您将他们的 user_id(或另一个更秘密的预定义加密字符串)(普通用户未知)作为字符串,并用随机预定义符号对其进行加盐,md5() 字符串并设置它作为 $_SESSION['user_code'] = $that_string; 并且无论何时该用户进入您盐分的页面,重复该过程并将其与 $_SESSION['user_code'] 匹配,如果它们不匹配;销毁会话。

所以在代码中它看起来像这样(例如):

 //user credentials are correct, user data is fetched from db   

$_SESSION['username'] = $row[3]; //username
$_SESSION['password'] = $row[2]; //password
$_SESSION['user_id'] = $row[4]; //user_id
$salt1 = 'uNs819';
$salt2 = 'J2i';
$user_code = $salt1 . $row[4] . $salt2;
$user_code = md5($user_code);
$_SESSION['user_code'] = $user_code;

然后在每个可用页面的开头检查这是否正确:

//fetch user credentials from db again
//$row4 is the user_id
if($_SESSION['user_code'] != md5($salt1 . $row[4] . $salt2){
    session_destroy();
}

我不认为使用 user_id 作为加密的一部分是最佳的,但这只是一个例子。最好我将使用创建用户时的时间戳的 md5 字符串。但是,如果我不清楚我的主要问题是这种方法对会话劫持是否有效,为什么/为什么不呢?

4

3 回答 3

1

您不需要具有多种盐的花哨方案。

此外,如果我可以窃取用户的会话 cookie,那么您的方案将根本不起作用。

  1. 登录后更改会话 ID 以避免会话固定

  2. 到处使用 HTTPS

  3. 使用 httpOnly 会话 cookie,以便 JavaScript 无法读取它

  4. 验证和拒绝 XSS 输入并在输出上转义用户生成的数据

  5. 使用长的随机会话 ID

  6. 重新验证用户的重要操作

于 2015-08-07T05:04:58.910 回答
0

“我遇到的另一种方法” - 请引用您的消息来源。

您在此处描述的内容完全不会影响会话劫持。不管你使用多少会话值、多少盐和多少轮加密,结果总是匹配的。如果会话被破坏,您不能依赖它来验证会话。session_regenerate_id() 函数确实增加了一点价值,但只会减少现有漏洞被利用的窗口。花时间防止会话受损 - 使用 https、HSTS、http-only+secure cookie 标志、严格的 CSP、到期时销毁会话。

如果您真的觉得需要进一步提高安全性,那么可以在正常交换中使用令牌,例如使用本地存储或设备指纹识别的质询响应。

于 2015-08-07T01:29:34.977 回答
0

始终根据跨站点伪造令牌检查任何表单,例如,在登录时为它们创建一个令牌:

Session:set('token', md5(uniqid());

然后在每个表单上放置一个带有所述标记的隐藏表单输入

<input type="hidden" name="crsf" value="<?php echo System::escape(Session::get('token'));">

然后您可以检查它们以确保:

if(Request::post('crsf') == Session::get('token'):
   //do what you gotta do

确保在每个表单提交上重新生成一个新令牌,无论它是否成功

对于为此使用方法,我深表歉意,但您了解了如何处理表单以及如何处理表单的要点。

于 2015-08-07T00:44:45.717 回答