我的 Web 应用程序几乎在整个应用程序中都使用了 UserId
。
UserId
的加密值吗? 任何建议...
最佳答案
注意: 取自 my previous answer 。
术语
了解 session
为了了解如何确保 session 安全,您必须首先了解 session 的工作原理。
让我们看看这段代码:
session_start();
一旦您调用它,PHP 将查找名为
PHPSESSID
(默认情况下)的 cookie。如果没有找到,它会创建一个:PHPSESSID=h8p6eoh3djplmnum2f696e4vq3
如果找到,则取
PHPSESSID
的值,然后加载相应的 session 。该值称为 session_id
。这是客户唯一知道的事情。您添加到 session 变量中的任何内容都保留在服务器上,并且永远不会传输到客户端。如果您更改
$_SESSION
的内容,该变量不会更改。它始终保持不变,直到您销毁它或超时。因此,尝试通过散列或其他方式混淆 $_SESSION
的内容是没有用的,因为客户端永远不会接收或发送该信息。然后,在新 session 的情况下,您将设置变量:
$_SESSION['user'] = 'someuser';
客户端永远不会看到该信息。
问题
当恶意用户窃取其他用户的
session_id
时,可能会出现安全问题。如果没有某种检查,他就可以自由地冒充该用户。我们需要找到一种方法来唯一标识客户端(而不是用户)。一种策略(最有效的)涉及检查启动 session 的客户端的 IP 是否与使用 session 的人的 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');
}
该策略的问题在于,如果客户端使用负载均衡器,或者(在长时间 session 中)用户拥有动态 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
被泄露,您就大功告成了。以上策略只是权宜之计。