简体   繁体   English

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

[英]PHP sessions unchecked when rapid navigation occurs

I have a session formed the following way: 我通过以下方式形成了一个会话:

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);
}

I use this on all my page by adding sec_session_start(); 我通过添加sec_session_start();在我的所有页面上使用它sec_session_start(); on my index page, which requires correct files depending on what page I am accessing. 在我的索引页面上,该页面需要正确的文件,具体取决于我访问的页面。

It works perfectly fine with slow navigation. 在缓慢的导航下,它可以很好地工作。

However, when rapid navigational clicks occur, for some reason it unchecked, and the user is logged out. 但是,当发生快速导航单击时,由于某种原因它未被选中,因此用户已注销。 How come? 怎么会?

This is the button I press rapidly. 这是我快速按下的按钮。 NOTE: It also changes the page from www.example.com to www.example.com/users , and then just repeats www.example.com/users until session is broken. 注意:它还会将页面从www.example.com更改为www.example.com/users ,然后重复www.example.com/users直到会话中断。

用户登录

And this is the result after about, 2-3 rapid clicks. 这是大约2-3次快速点击后的结果。 Works fine when pressed 1-2 times a second, max. 每秒最多按下1-2次,效果很好。

用户已注销

I have tried not using it as a function, and putting it on the absolutt TOP of the page without success. 我尝试不将其用作函数,而是将其放在页面的绝对TOP上没有成功。

The error seems to be session_regenerate(true) . 该错误似乎是session_regenerate(true)

This command generates a new session id. 该命令生成一个新的会话ID。 The parameter will delete the old session file if it is set to true. 如果该参数设置为true,则将删除旧的会话文件 In this code it is set to true, so the session is created an started and then directly closed and deleted. 在此代码中,将其设置为true,因此将创建一个启动会话,然后直接关闭并删除该会话。

I think it appears only a few times because the command is called after session_start() was called and the output already started. 我认为它只出现了几次,因为在session_start()被调用并且输出已经启动之后才调用命令。

Try changing the parameter to false . 尝试将参数更改为false For the right use of session_regenerate() look into this question . 为了正确使用session_regenerate()查看此问题

You appear to be discarding the old session ID on every page load. 您似乎在每次页面加载时都将丢弃旧的会话ID。 This is unnecessary, inefficient, and causes breakage. 这是不必要的,效率低下的,并且会导致损坏。

If you navigate twice in quick succession what can happen here is: 如果快速连续浏览两次,可能会发生以下情况:

  • the first request hits the server and starts executing your PHP, causing session_regenerate_id(true) to destroy the old session 第一个请求到达服务器并开始执行PHP,导致session_regenerate_id(true)破坏旧会话
  • this will cause the response from the PHP script to include a Set-Cookie: sessionid=something header, asking the browser to update its cookie to point to the new session 这将导致来自PHP脚本的响应包括Set-Cookie: sessionid=something标头,要求浏览器更新其cookie以指向新会话
  • but the browser hasn't received the response from the script quite yet 但浏览器尚未收到脚本的响应
  • you click a second time 你第二次点击
  • the browser discards the existing request. 浏览器将丢弃现有请求。 Any Set-Cookie header isn't going to get listened to now 现在没有Set-Cookie标头会被收听
  • the browser makes a new request to your server. 浏览器向您的服务器发出新请求。 The browser doesn't know anything about a new session, so it includes the old session cookie 浏览器对新会话一无所知,因此其中包含旧的会话Cookie
  • your script sees the old session cookie, which points to nothing, so user has to start a new session which isn't logged in 您的脚本看到了旧的会话cookie,该会话指向什么都没有,因此用户必须启动一个未登录的新会话。

If you have an anti-Cross-Site-Request-Forgery system based on storing a synchroniser token in the session, then regenerating the session ID on every page load will also make any forms you use inoperable when the browser has multiple tabs open on the site at once, or when the user navigates with the Back button. 如果您有一个防跨站点请求伪造系统,该系统基于在会话中存储同步令牌的功能,则当浏览器在浏览器上打开多个选项卡时,在每次页面加载时重新生成会话ID也会使您无法使用任何表单。一次,或当用户使用“后退”按钮导航时。

You should only session_regenerate_id when the authentication associated with a session is changed (primarily, when the user logs in). 仅在更改与会话关联的身份验证时(主要是在用户登录时),才应使用session_regenerate_id

Changing session IDs does not prevent session fixation; 更改会话ID不会阻止会话固定。 it is only a mitigation for when session fixation has already occurred through some other means (eg a vulnerable app on a neighbour subdomain injects a cookie into the shared parent domain). 这仅是通过某些其他方式进行会话固定的缓解措施(例如,相邻子域上的漏洞应用将Cookie注入共享的父域)。

If you didn't change the session ID, then an attacker who had already gained session fixation could get a full session hijack, by giving you a session ID she already generated and knows, and letting you log in using that session, upgrading it to an authenticated session. 如果您不更改会话ID,则已经获得会话固定的攻击者可以通过提供您已经生成并知道的会话ID,并让您使用该会话登录并将其升级为完整版本,从而劫持整个会话。经过身份验证的会话。 When you change the session ID on auth boundaries that isn't possible; 当您无法在身份验证边界上更改会话ID时, the worst she can do now is push you into a session in which you are unexpectedly logged in as her. 她现在能做的最糟糕的事情就是将您带入一个会话,使您意外地以她的身份登录。 Which isn't ideal, but generally this constitutes a much less damaging attack. 这不是很理想,但是通常这构成的破坏性攻击要少得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM