我正在尝试构建自己的安全PHP会话类,当时我实际上想知道是什么阻止了某人模拟会话?
IE,为什么代码不进行测试.php
$_SESSION['logged_in'] = true;
无法处理索引.php其中
if($_SESSION['logged_in'] == True){
echo 'logged in';
}
我知道这样做的方法是通过将会话锁定到 IP 地址和用户代理来生成安全 ID,但这究竟是如何工作的?
这意味着如果我能够猜出会话 ID 我是否能够设置 $_SESSION['logged_in'] = true 并模拟登录?然后我是否应该将 SESSION 变量更改为更安全的变量以检查登录
?很抱歉我的问题,希望我说得有道理...
首先,会话数据仅存储在服务器上,因此外部客户端不能简单地创建自己的会话数据并将其发送到您的服务器。
因此,它归结为实际猜测其他人的会话标识符并假设他们的身份; 这是相当困难的,但并非不可能。在攻击者可以利用受害者和您的服务器之间的网络流量的情况下,完全不可能阻止它们。
不过,您可以采取一些措施来使事情更安全:
-
使用 SSL;另请参阅
session.cookie_secure
。 - 从良好的随机来源生成标识符,即
/dev/urandom
在 Linux 机器上;另请参阅session.entropy_file
。 - 在用户登录或注销时重新生成标识符;另请参阅
session_regenerate_id()
- 使用 HttpOnly Cookie(且仅限 Cookie(永久保存会话标识符;另请参阅
session.use_only_cookies
和session.cookie_httponly
。 - 使用严格的会话;另请参阅
session.use_strict_mode
。
在 会话中保留用户代理的计算哈希,并确保它不会更改,例如:
$_SESSION['_agent'] = sha1($_SERVER['HTTP_USER_AGENT']);
尝试尽可能缩短会话的生存期,并使用高级"记住我"功能在会话过期时重新生成会话。
了解潜在劫持何时发生并在发生时采取适当措施也很重要。您需要跟踪哪些会话属于哪个用户,以便在其中一个会话被破坏时可以使所有会话无效。
顺便说一句,将会话锁定到IP地址是很棘手的;一些ISP会让人觉得用户来自不同的地址,或者多个用户来自同一个地址。无论哪种方式,最好跟踪用户代理,因为这不太可能改变。
猜测会话 ID 不是会话劫持。这比猜测密码更难。但是,是的,如果有人确实获得了会话ID,他们将获得对相关帐户的完全访问权限。
按 ID 地址锁定仅意味着您存储用户在会话本身中登录时使用的原始 IP 地址,并在每个请求开始时检查它以查看它是否没有更改。这样,即使攻击者获得了正确的会话 ID,他们仍然无法使用它。
关于这个主题,有一篇很好的维基百科文章,以及相关的StackOverflow问题:1,2。