PHP-会话标识符-安全性
我有一个关于使用全局PHP-会话标识符-安全性,php,security,session,ssl,session-variables,Php,Security,Session,Ssl,Session Variables,我有一个关于使用全局$\u SESSION[]变量的问题 现在对于我的web应用程序,每当用户登录时,都会返回与该用户名和特定密码匹配的行。然后我获取列user\u hash,并将该user\u hash存储在$\u会话['id']中 我使用此会话来识别哪个用户已登录,并基于此唯一哈希执行数据库查询。我在某个地方读到过这样一个“静态”标识符(静态标识符是用户\u散列,因为它永远不会改变)是不安全的,我宁愿让用户\u散列动态地改变 因此,我实现了一个系统,每当用户登录和/或导航到web应用程序中的
$\u SESSION[]
变量的问题
现在对于我的web应用程序,每当用户登录时,都会返回与该用户名和特定密码匹配的行。然后我获取列user\u hash
,并将该user\u hash
存储在$\u会话['id']
中
我使用此会话来识别哪个用户已登录,并基于此唯一哈希执行数据库查询。我在某个地方读到过这样一个“静态”标识符(静态标识符是用户\u散列,因为它永远不会改变)是不安全的,我宁愿让用户\u散列动态地改变
因此,我实现了一个系统,每当用户登录和/或导航到web应用程序中的其他页面时,我都会生成一个新的哈希,将其存储在数据库中,然后将其存储在全局$\u会话['id']
变量中。我设法做到了这一点,但现在每当有人试图从两台设备登录时,具有“旧”会话的设备无效,因为用户\u哈希从新设备更改,并注销具有旧会话的用户
我的问题是,这样做真的有意义吗?我在我的Web服务器上使用ssl(https),所以会话劫持相对来说是不可能的?如果仅使用静态会话标识符存在安全缺陷,是否有更好的方法使其动态化,同时不注销其他用户?两个有用的链接:
我设法做到了这一点,但现在每当有人试图从两台设备登录时,具有“旧”会话的设备无效,因为用户\u哈希从新设备更改,并注销具有旧会话的用户 虽然这可能取决于您的安全要求,但我在上面发布的帖子说: 将旧会话标记为已过时,并将其标记为在十秒钟内[或在适合您需要的某个时间]过期。这样,任何排队的请求仍然可以访问过期的会话,但我们不必让它永远打开
因此,我实现了一个系统,每当用户登录和/或导航到web应用程序中的其他页面时,我都会生成一个新的哈希,将其存储在数据库中,然后将其存储在全局$u会话['id']变量中 就我个人而言,我怀疑这是非常有效的,并将导致您的服务器负载这一不断的改造,巨大的开销。这是不需要的 如果您真的想重新创建会话,只需使用
session\u regenate\u id()
并将其设置为时间值(比如每10分钟一次),如本文顶部所示
唯一重要的是会话标识。浏览器或最终用户永远看不到会话数组中的所有值
所以,;只要会话id是一个long随机值,它就会隐藏在可见的地方。有关如何确保PHP提供更多随机和更长命名会话ID的详细信息,请参阅
php.ini:
如果在数据库中存储会话,请确保会话id的列名足够长,否则由于会话名称被截断,会话将永远无法连接
其他一些因素:
- 确保您的会话cookie被PHP设置为
。无论TLS连接的状态如何,都必须手动执行此操作。请参见上面的加密的
session.cookie\u secure=1
- 您可以通过添加浏览器或ip特定数据(例如,这些相应的
值的散列)来帮助最小化已经不太可能发生的Hjack事件,以便在执行warrent重复检查会话的任务时进行比较,以比较浏览器类型/客户端ip是否仍然与会话记录中的内容进行比较。这两种方法中的每一种都可能存在问题,例如,移动连接上的少数人可能在登录期间更改IP,或者多个设备上的用户可能在每个设备上都有不同的浏览器,但根据需要找到一种方法进行比较(这也在页面顶部的中引用)$\u SERVER
- 如上所述,
数据从未存储在客户机上,因此从数据库中散列值以存储在$\u会话
中很可能超出您的安全需要$\u会话
- (单个)最重要的是会话id是安全的,并且足够大,可以舒适地容纳一个潜在的黑客使用假会话id钓鱼,作为在雷舰上玩战舰的近亲
static function regenerateSession()
{
// If this session is obsolete it means there already is a new id
if(isset($_SESSION['OBSOLETE']) || $_SESSION['OBSOLETE'] == true)
return;
// Set current session to expire in 10,30,100 seconds etc.
$_SESSION['OBSOLETE'] = true;
$_SESSION['EXPIRES'] = time() + 10; //or 30 seconds or whatever.
// Create new session without destroying the old one
session_regenerate_id(false);
// Grab current session ID and close both sessions to allow other scripts to use them
$newSession = session_id();
session_write_close();
// Set session ID to the new one, and start it back up again
session_id($newSession);
session_start();
// Now we unset the obsolete and expiration values for the session we want to keep
unset($_SESSION['OBSOLETE']);
unset($_SESSION['EXPIRES']);
}
session.save_handler = files
session.use_cookies = 1
session.cookie_secure = 1
session.use_only_cookies = 1
session.cookie_domain = "example.com"
session.cookie_httponly = 1
session.entropy_length = 32
session.entropy_file = /dev/urandom
session.hash_function = sha256
session.hash_bits_per_character = 5