我的Web应用程序UserId
几乎在整个应用程序中使用..
什么是在PHP中保护会话变量的最有效方法?
会话容易受到攻击吗?
我应该保留UserId
会话中的加密值吗?
任何建议......
注意:取自我之前的回答.
术语
用户:访客.
客户端:安装在特定计算机上的特定Web功能的软件.
为了了解如何确保会话安全,您必须首先了解会话的工作方式.
让我们看看这段代码:
session_start();
一旦你调用它,PHP就会寻找一个名为PHPSESSID
(默认情况下)的cookie .如果找不到,它将创建一个:
PHPSESSID=h8p6eoh3djplmnum2f696e4vq3
如果找到,则取值,PHPSESSID
然后加载相应的会话.该值称为a 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'); }
该策略的缺点是,如果客户端升级它的浏览器或安装一个插件(一些添加到用户代理),用户代理字符串将更改,它将触发虚假警报.
另一个策略是旋转session_id
每5个请求.这样,从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
受到了损害,那么您已经完成了很多工作.上述策略只是权宜之计.