发生快速导航时未选中 PHP 会话

Posted

技术标签:

【中文标题】发生快速导航时未选中 PHP 会话【英文标题】:PHP sessions unchecked when rapid navigation occurs 【发布时间】:2016-05-11 19:06:57 【问题描述】:

我有一个按以下方式形成的会话:

function sec_session_start() 
$session_name = 'primary_session';
$secure = false;
$httponly = true;
if (ini_set('session.use_only_cookies', 1) === FALSE) 
    header("Location: /error?e=1");
    exit();

$cookieParams = session_get_cookie_params();
session_set_cookie_params(3600,$cookieParams["path"],$cookieParams["domain"],$secure,$httponly);
session_name($session_name);
session_start();
session_regenerate_id(true);

我通过在我的索引页面上添加 sec_session_start(); 在我的所有页面上使用它,这需要正确的文件,具体取决于我正在访问的页面。

它在缓慢的导航下工作得很好。

但是,当发生快速导航点击时,由于某种原因未选中它,并且用户已注销。 怎么会?

这是我快速按下的按钮。注意:它还将页面从www.example.com 更改为www.example.com/users,然后重复www.example.com/users 直到会话中断。

这是大约 2-3 次快速点击后的结果。每秒最多按下 1-2 次即可正常工作。

我试过不把它当成函数用,放在页面绝对TOP上也没成功。

【问题讨论】:

我认为,这可能是您的浏览器的一个功能。也许当您的浏览器看到您正在尝试重新加载页面时,会在缓存和 cookie 被清除的地方进行完全重新加载,以便会话 cookie 不再可用并且您已注销。 (这是我的想法,我没有测试任何东西。) 在所有浏览器中发生,包括最新的 Safari 和 Mozilla 更新。此外,cookie 时间为 1 小时。 @Reflic 同意,但是,这可能是 php.ini 问题吗?我没有这样的文件并使用所有标准选项.. @Reflic 如果你能投票以引起更多关注,我会很高兴。真是个奇怪的问题。从来没有经历过... 我想我发现了错误。你为什么在这里使用“session_regenerate()”? 【参考方案1】:

错误似乎是session_regenerate(true)

此命令生成一个新的会话 ID。如果设置为 true,该参数将删除旧的 会话文件。在这段代码中,它被设置为 true,因此会话被创建并启动,然后直接关闭和删除。

我认为它只出现了几次,因为该命令是在调用 session_start() 并且输出已经开始之后调用的。

尝试将参数更改为false。 要正确使用session_regenerate(),请查看this question。

【讨论】:

编辑:是的,它有效。只是花了一些时间来完成更新。谢谢!但是,快速提问,我怎样才能防止这种情况发生,但仍然可以避免会话固定攻击? 当我正确理解另一个问题时, session_regenrate() 可以防止您遭受会话固定攻击,同时也不会删除会话数据。【参考方案2】:

您似乎在每次页面加载时都放弃了旧的会话 ID。这是不必要的、低效的,并且会导致损坏。

如果您快速连续导航两次,这里可能发生的情况是:

第一个请求到达服务器并开始执行您的 PHP,导致 session_regenerate_id(true) 销毁旧会话 这将导致来自 PHP 脚本的响应包含 Set-Cookie: sessionid=something 标头,要求浏览器更新其 cookie 以指向新会话 但浏览器还没有收到脚本的响应 您再次点击 浏览器丢弃现有请求。现在不会听到任何 Set-Cookie 标头 浏览器向您的服务器发出新请求。浏览器对新会话一无所知,因此它包含旧会话 cookie 您的脚本会看到旧的会话 cookie,它没有指向任何内容,因此用户必须启动一个未登录的新会话

如果您有一个基于在会话中存储同步器令牌的反跨站点请求伪造系统,那么在每次页面加载时重新生成会话 ID 也会使您在浏览器具有多个选项卡时使用的任何表单都无法使用立即在网站上打开,或者在用户使用“后退”按钮导航时打开。

您应该只在与会话关联的身份验证发生更改时(主要是用户登录时)session_regenerate_id

更改会话 ID 不会阻止会话固定;这只是通过其他方式(例如,邻居子域上的易受攻击的应用程序将 cookie 注入共享父域)发生会话固定时的一种缓解措施。

如果您没有更改会话 ID,那么已经获得会话固定的攻击者可以通过向您提供她已经生成并知道的会话 ID 并让您使用该会话登录来获得完整的会话劫持,将其升级为经过身份验证的会话。当您更改身份验证边界上的会话 ID 时,这是不可能的;她现在能做的最糟糕的事情就是把你推到一个会话中,在这个会话中你意外地以她的身份登录。这并不理想,但通常这构成的破坏性要小得多。

【讨论】:

所以基本上我在登录/注销时使用它?或者每当我需要更改密码时? :) 当然在登录和任何导致身份验证的替代路径(例如注册、忘记密码)时。一些应用程序可能具有不同身份验证级别的概念,这也需要它(例如,您可以持续“登录”,但在执行敏感操作之前仍需要重新身份验证),另外,如果您有更改用户功能。出于一致性考虑,可能可以包括注销,但我想不出任何涉及修复会话的攻击,然后该会话变得 less 特权。

以上是关于发生快速导航时未选中 PHP 会话的主要内容,如果未能解决你的问题,请参考以下文章

PHP include用于导航,选中/突出显示当前页面

使用 Chrome API 时未选中 runtime.lastError

使用useState(Reactjs)时未选中材料表复选框

复选框设置日期,但在表单加载时未选中:需要加载事件吗?

如果提交表单时未选中复选框,如何将布尔值更新为 0

在 C# 中的运行时未选中复选框时禁用文本框