PHP会话本身对于登录来说安全吗?

3

可能是重复问题:
当用户登录时,我需要在php会话中存储什么?

我想使用php会话来让用户登录。一旦我验证了他们的身份,我会把他们的user_id和has_logged_in存储在一个会话中。为了验证他们是否已登录,我会检查他们的用户id是否设置,并且“has_logged_in”是否为true。偶尔,我会通过session_regenerate_id(true)重新生成会话ID。这样做就足够安全了吗?还是我必须采取进一步措施来防止劫持和其他会话安全漏洞?


1
你不需要存储 has_logged_in,只需在注销用户时使用 $_SESSION = array(); 即可。 - Daniel Lubarov
2个回答

7

术语

  • 用户:一个访问者。
  • 客户端:安装在特定机器上的特定网络能力软件。

了解会话

为了理解如何使您的会话安全,您首先需要了解会话的工作原理。

让我们看一下这段代码:

session_start();

今日免费次数已满, 请开通会员/明日再来
PHPSESSID=h8p6eoh3djplmnum2f696e4vq3

如果找到了PHPSESSID的值,它将加载相应的会话,并将该值称为session_id。这是客户端唯一知道的内容。无论您向会话变量中添加什么内容,都将保留在服务器上,永远不会传输给客户端。如果更改$_SESSION的内容,该变量不会改变。它始终保持不变,直到销毁或超时。因此,尝试通过哈希或其他手段来混淆$_SESSION的内容是无用的,因为客户端从未接收或发送该信息。
然后,在新会话的情况下,您将设置变量:
$_SESSION['user'] = 'someuser';

客户端永远不会看到这些信息。

问题

当恶意用户窃取另一个用户的session_id时,可能会出现安全问题。如果没有某种检查,他将可以自由地冒充该用户。我们需要找到一种方法来唯一地识别客户端(而不是用户)。

其中一种策略(最有效的一种)是检查启动会话的客户端的IP是否与使用会话的人的IP相同。

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}

// The Check on subsequent load
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
    die('Session MAY have been hijacked');
}

那种策略的问题在于,如果客户端使用了负载均衡器,或者(在长时间会话中)用户具有动态IP,则会触发错误警报。

另一种策略是检查客户端的用户代理:

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
}

// The Check on subsequent load
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) {
    die('Session MAY have been hijacked');
}

那种策略的缺点是,如果客户端升级了浏览器或安装了插件(某些插件添加到用户代理),则用户代理字符串将更改,并触发虚假警报。
另一种策略是在每5个请求中轮换session_id。这样,理论上session_id不会被劫持太久。
if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['count'] = 5;
}

// The Check on subsequent load
if(($_SESSION['count'] -= 1) == 0) {
    session_regenerate_id();
    $_SESSION['count'] = 5;
}

你可以根据自己的需求组合这些策略,但你也会合并它们的缺点。
不幸的是,没有一种解决方案是百分之百可靠的。如果你的session_id被攻击者获取,那么基本上就无法挽回了。以上策略只是一时的应急措施。

+1 详情请见 - Aziz
你本可以只提供一个链接到你的另一个回答,而不是复制粘贴。 - Phil
@Phil:我在原始问题中标记为重复时已经这样做了。这位用户在这里寻找答案,我也提供了答案。 - Andrew Moore
谢谢!很抱歉重复提问,但这个答案非常有帮助。 - Rain
一个 session_id 如何被劫持?我相当自信我的登录系统,直到我看到这篇文章。 - sooper
@sooper:要么是安装在受害者计算机上的恶意软件,将所有cookie信息发送到远程服务器,要么就是检查未加密的流量。 - Andrew Moore

0

这只是我的观点,只要您不需要访问需要用户ID和密码的数据库,它就足够安全。如果您要存储该用户ID以访问某些内容,则必须注意SQL注入漏洞,我认为您已经知道这些了。

仅将其用于像您提到的条件一样的条件将足够安全。那就是我使用的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接