可能重复:
What do I need to store in the php session when user logged in?
我想使用php会话来记录用户。一旦我验证了他们的身份,我会在会话中存储他们的user_id和has_logged_in。为了验证他们是否已登录,我将检查他们的用户ID是否已设置且has_logged_in是否为true。偶尔,我会通过session_regenerate_id(true)重新生成会话ID。这是否足够安全,还是我必须采取进一步措施来防止劫持和其他会话安全漏洞?
答案 0 :(得分:7)
为了了解如何确保会话安全,您必须首先了解会话的工作方式。
让我们看看这段代码:
session_start();
一旦你调用它,PHP就会寻找一个名为PHPSESSID
的cookie(默认情况下)。如果找不到,它将创建一个:
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 :(得分:0)
只是我的意见,只要你不需要访问一个需要用户ID和密码的数据库,它就足够安全了。如果您要存储该用户标识以访问某些内容,您必须了解SQL注入漏洞,我想您应该知道这些。
使用它只是为了像你提到的条件一样足够安全。这就是我用过的东西。