我正在做一些关于如何正确设置会话和防止劫持等StackOverflow的研究。我找到了一个答案,有人贴在一个问题上,他提供了以下代码:
当用户登录时,用户名和密码匹配
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] .''. $_SERVER['REMOTE_ADDR']);
检查用户是否登录,对于受保护的页面:
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] .''. $_SERVER['REMOTE_ADDR'])) {
session_destroy();
header('Location: login.php');
exit();
}
它似乎工作得很好,但我的问题是:这有多安全,这是一个好方法还是我应该尝试其他东西?这篇文章没有点赞什么的,所以不确定它是否好。
另外,不确定如何获取关于这个会话的用户的信息。我需要在数据库中存储任何东西吗?
谢谢!
这段代码有两个主要问题。
1) IP地址因合法原因而改变。如果客户端在负载均衡器后面,比如在公司网络中,那么他将无法使用您的web应用程序。
2)检查用户代理很像拥有一个表示?is_hacker=false
的get变量。如果黑客有了会话id,他就有了用户代理,这很容易被欺骗。
更重要的是,我不知道为什么在做纯文本比较实际上更安全的时候,你会想要使用md5。因为用户代理是第一个,攻击者可以使用md5前缀攻击来产生冲突,并且可以绕过REMOTE_ADDR检查。(一个有用的md5冲突攻击不会经常出现,但是这个很有趣!)
即使有了这个检查,CSRF和XSS仍然可以用来影响会话。XSS可用于读取CSRF令牌,然后使用XHR发出攻击者想要的任何请求。有人可能会说这是在试图减轻OWASP的攻击,但实际上您需要使用SSL来保护会话id。
这看起来是一个很好的方法,但是指纹散列是由客户端数据生成的,可以被欺骗。用于登录表单的一个好方法是生成一个随机令牌,该令牌存储在会话中并通过表单传递。一旦令牌被验证(或未验证),它应该被取消设置,仅用于一次使用。
会话还应该存储用户id,一旦用户登录检索存储在数据库中的用户信息。
我同意Rook的评论,这是对你的代码的一个很好的分析。
要确保PHP会话的安全需要考虑很多问题,但是使用最新版本的PHP,这并不难实现,以下是需要考虑的问题:-会话文件存储在服务器上的位置(如果是共享服务器,主要是一个问题)-为客户端之间的所有敏感数据和cookie使用安全连接服务器-尽你所能使客户端的cookie会话ID安全—不在会话变量中存储任何敏感数据至于在数据库中存储东西,这取决于你的需要,但我想说你可能不需要它,并且在会话变量中存储数据对于安全来说是很好的,只是(正如我已经说过的)不要在那里存储任何敏感的东西。从另一个位置(很可能是数据库)检索敏感数据。
如果你需要了解更多关于PHP会话安全的知识,我有一系列关于这个主题的博客文章。