Why are session variables retained between different users on the same PC? - php

My Laravel PHP application stores various user interface states using Session::put().
I was surprised to discover that session variables seem to be retained between different users who log in sequentially on one PC. For example:
log in as user1, set some UI options, log out
log in as user2, expect to see default UI options, actually see user1's options
I've tried with native and database session drivers.
Why are session variables retained between different users on the same PC? Wouldn't this be regarded a security defect? Is this a Laravel or general PHP issue, or my implementation? What's the correct solution?

Why are session variables retained between different users on the same PC?
Presumably because they are logging out of your application, but not the user environment for the OS and are not closing the browser either.
Wouldn't this be regarded a security defect?
It is more a case of bad security practices on the part of the end users.
Is this a Laravel or general PHP issue, or my implementation? What's the correct solution?
Clear the session data when the user logs out.

Why are session variables retained between different users on the same
PC?
You are mistaking "sessions" and "auth". They are not the same thing.
You can have a "session" without being logged into Laravel (or most web applications).
When you log in to an application, that is simply added onto your current session. But when you logout of the application your current session continues, just without the auth bit.
What's the correct solution?
If you want to clear the session of all data - you must flush it:
Auth::logout();
Session::flush();
(note - the comment suggestion above to use Session::regenerate() is incorrect - that will only regenerate the session ID - not the data - it will remain)

Related

Will PHP code of an app always have read/delete access to session files on the same server?

For my Joomla! 3.8+ extension I need to be able to find and delete (unlink) PHP session files (named 'sess_' + session id) which will be stored in the session_save_path, e.g. /tmp. I understand that it is PHP who is storing the session files, i.e. not Joomla! (Joomla! session handler set to 'PHP')
My question: Will a PHP session file that is created through the use of the Joomla! website ALWAYS be read/write accessible by my extension's PHP code which is part of the same Joomla! install?
Addition: I realised later, that I omitted the word 'always' in my question, which I have now added.
Addition: More in-depth explanation about what I am trying to achieve.
As I said I have a Joomla! site, where users can log into.
The issue applies ONLY when Joomla! is configured with Session Handler set to 'PHP' (instead of 'database'). When Session Handler is 'database', there is no problem.
In basic terms, I want to achieve the following (with Joomla! session handler set to 'PHP'):
1> A user opens browser A and logs into the website and Joomla!
records the related session ID plus user ID in a database.
2> The same user opens a different browser B (maybe at a different IP)
and wants to log into the same website.
3> Because user has already logged into the website through browser A,
he/she is not allowed to log in again and will be presented a
clickable link that will destroy all his other sessions, including the
one with browser A (we have recorded the session IDs of all the other
sessions).
A mere session_destroy() in step 3 is just partly doing the trick, because the destroyed session details reappears after a little while at the Joomla! backend and also in the Joomla! session table. Although this does not interfere with the Joomla! front-end, it is not clean and I want to avoid it, to make it fool proof.
By far the best solution is if I could delete the PHP session file (for example in dir /tmp and named 'sess_....'). I have tested this and it worked fine. However... it relies upon always having delete access to the PHP session file (using session_save_path() and unlink($session_file_path)) and this is the basis of the question that I posted.
I found out that the delete of the PHP session file is not always possible; it depends on the providor's PHP config. Since it is a commercial app that I am developing, the process must work on all configs, i.e. including those that do not allow delete access to the session file.
I will continue my search for a solution and will post it here when I found it.
What you want is often possible but it poses a security risk (just think: one user can read session files before knowing who they belong to, so also those of other users), and therefore security-conscious ISPs will endeavour to prevent this.
So even if you manage to do this, nothing assures you that your code isn't going to break should the ISP tighten its security in the future. This makes for some maintenance uneasiness.
A better solution would be to have a secondary table of invalidated session-ids.
Then you write a user plugin hooking the onUserAuthorization and onUserLogout events. You will need onAfterInitialise too.
This hook will check upon initialisation whether the current session ID has been invalidated; if it is, immediate logout is triggered. Otherwise, its timestamp is updated.
On user logout, the current session id is removed from the table and the session destroyed.
At a fresh login, a warning about other sessions being open is issued: if login succeeds, all other sessions for the same user will be marked as invalidated.
As a maintenance task, all entries with a timestamp older than maximum session lifetime may safely be expunged.
That depends on the server settings.
Find the user PHP is using: How to check what user php is running as?
Check the permissons of that user on the folder where the sessions are stored: Unix: How to check permissions of a specific directory?
Change the permissions when needed: https://serverfault.com/questions/105535/how-can-i-set-full-premissions-to-a-user-in-a-specified-dir
Thank you #Nigel and #AgeDeO
By trial and error, I found out that the answer is NO, not always.
By executing the code with a few commercial ISPs, I hit one ISP who did not allow me to delete the PHP session file while it was at its default location. The location was /var/lib/php5.

PHP how to manage multiple session in same browser using cookies?

I'm new to PHP, I read other articles without finding the answer I'm looking for, but still don't know if what I want to do makes sense or not.
I'm using PHP 7.
My user authentication page, checks credentials and then executes session_start(), creating the session server-side and a cookie client-side in the browser.
Each other page of the web application then calls session_start() to resume session information, in this case checking the cookie. Everything works fine so far... at least when I have a single login.
I'd like to be able to have more than one user SIMULTANEOUSLY logged in the same browser (on another tab for example.) using cookie. I don't want to append the session ID to the URL.
I managed to create different session on the server-side using session_id() before session_start() in the authentication page based on username, but the problem is on the client side.
The first successful login (session_start()) creates a cookie and the second login updates the same cookie corrupting the previously created session.
Therefore when it comes to resume the session, session_start() will resume only the last session, mixing the data fetched from DB based on session info.
Is there a way to make session_start() create a cookie for each login and make PHP resume the correct session using cookies?
Any ideas?
FURTHER DETAILS:
I'm updating a legacy app trying to fix some security issue. The need for multiple sessions comes from administrative purposeses where admins access the same site. The reason why it's needed a separation of session is that depending of the session info, the data are fetched from a different database. Therefore, a regular usage would only need one session per user, but the administrator he needs to make multiple logins viewing different data depending on that login.
The default PHP behaviour is to handle sessions using cookies.
..and the default behaviour for browsers is to "reuse" the same set of cookies if you revisit an URL in another tab.. So, like mentioned below:
The simple way probably is to start another browser. Not the same browser but like firefox and chrome, if you have multiple browsers installed.
Another way would be to install a browser plugin, like Sessionbox for Chrome or Multifox for Firefox.
Edit, for clarity: I can think of two cases when multiple sessions would be used:
During development. Depends on the application, but an obvious case would be testing communication between two users.
After deployment. Though I've never seen a site that required multiple logins for the same user account.
This is my frame of reference. Based on this I assumed the question was for development. I'm not suggesting that the site should require installing extra packages. Flash would be about the only one that's ever gotten away with that..
You can use the same session but change the variable names that you are looking for:
if ( $_SERVER['REQUEST_URI'] == '/admin/' ):
$session_name = 'session1';
else:
$session_name = 'session2';
endif;
session_start( $session_name );

Should I use Session variables or the global supervariable

I have a small situation here but I wanted to try and be sure I was approaching this in a correct way.
I have a web application that is used by several shops.
Each shop is authenticated through htaccess and htpasswd in order to connect to the correct database.
This portion works great!
Each shop has multiple employees but each employee uses a separate computer/workstation.
So it goes Shop logs in, gets authenticated, connects to proper database and then loads a login page.
At the login page the user logs into the application using name and password, and they are good to go.
At this point I am loading user information (UserID, Security Level, etc) into the session.
Part of my problem is trash collection as every once in awhile the session variables are getting lost.
Every page has session start as the first thing so I imagine after an hour or so of inactivity the session is getting collected by the trash collector and poof, it is gone.
I am toying with the idea of loading the user information into the $GLOBALS supervariable to avoid losing the session due to inactivity.
Now, I realize that there are ways to delay/stop the trash collector in PHP but it seems to me if I use the global scope it removes the need for extra coding or configuring of PHP.
Am I correct in assuming that as long as each user is on their own machine accessing the site that using the $GLOBALS will only apply to each user?
Think you have a general misconception of session and global variables.
Global variables are the variables which remain common for the whole
application… Their value can be used across the whole application
whereas Session variables are variables which remain common for the
whole application but for one particular user. They also can be used
across the whole application… But they die when a particular user
session ends.
https://stackoverflow.com/a/14848246/1022914
I recommend using sessions though. Check the user details against user data stored in a database. If it passes authentication, create session variables with user data to be used across your pages. This makes thing a whole lot easier
You can use cache . It can help u to keep user logged in always , as facebook .

Chrome: "continue where I left off" mode and Symfony2

Using Symfony2 and FOSUserBundle, I am not getting the expected behavior on the following implementation.
To begin, know that Continue where I left off option in Chrome restores completely the user session independently of having checked some "Remember me" or something like that. Therefor,it saves a cookie with all the information of the session.
What I am trying to do is to avoid the creation of a session from the cookie stored through that Continue where I left off option on Chrome.
Or, if I cannot avoid the creation of the session, at least try to know that the session comes from that completely transparent way.
I have found this in Symfony2 documentation (specifically here):
In some cases, however, you may want to force the user to actually re-authenticate before accessing certain resources. For example, you might allow "remember me" users to see basic account information, but then require them to actually re-authenticate before modifying that information.
The security component provides an easy way to do this. In addition to roles explicitly assigned to them, users are automatically given one of the following roles depending on how they are authenticated:
IS_AUTHENTICATED_ANONYMOUSLY - automatically assigned to a user who is in a firewall protected part of the site but who has not actually logged in. This is only possible if anonymous access has been allowed.
IS_AUTHENTICATED_REMEMBERED - automatically assigned to a user who was authenticated via a remember me cookie.
IS_AUTHENTICATED_FULLY - automatically assigned to a user that has provided their login details during the current session.
So, if I don't get it wrong, a user that transparently logs in as a result of the Copntinue where I left off option, should have the IS_AUTHENTICATED_REMEMBERED.
Well, the reality is that it is not thus. The reality is that the granting is IS_AUTHENTICATED_FULLY.
Has anyone passed through this?
Any idea on all this?
Thanks
Sessions are handled server side. Depending on your server's configuration for sessions lifetime, you can close your browser and re-open it without losing the session. This has nothing to do with the Continue where I left off option of Google Chrome.
The granting is IS_AUTHENTICATED_FULLY because the session is still active on the server and not because of the Google Chrome option.
Simple example use case. Let's say we set a 5 minutes session lifetime.
Without the remember me option :
I log in : a session is created on the server.
I close the browser.
I come back 10 minutes later : session has expired therefore I have to provide my credentials.
With the remember option :
I log in : a session is created on the server AND a cookie is created on my browser saying hey I'm connected.
I close the browser.
I come back 10 minutes later : session has expired BUT as the result of the cookie saying hey I'm connected, a new session will be automatically created. Therefore I will not have to provide my credentials again.
In both case if you come back within the first 5 minutes you will be automatically logged in because the server still handle a session for your browser.

Handling user login tokens

So I want users to be able to login from different computers simultaneously. So that means I should allow the user to have multiple tokens. And then I also want the user to be able to login from different browsers on the same computer. So that means I should allow the user to have multiple tokens for same IP. However, it's gonna get messy because eventually I'm going to have alot of tokens for one user!
Any suggestions on strategy of controlling this or am SOL that I would need to do a token clean up for tokens that are not used for say 15 days or so? Sorry, I just want to get it right :)
P.S. I'm doing this with PHP
Not sure what kind of answer you are waiting for, but you might want to use the Session Handling mecanism that comes with PHP, to store the data of your users' sessions.
It's based on a cookie that's used to store the "token" that points to the session -- which means each user can have a distinct session on each one of bots his browsers and computers ; and works pretty fine.
With that, you just have to call session_start() at the beginning of your script, and use $_SESSION in it -- and that's pretty much everything you have to care about : PHP will deal with sessions' expiration itself.
Just use PHP's built-in session controls. It will automatically generate a token for each session, which is saved in a cookie. You can then have a login flag (for example $_SESSION['login']) that you set to true once the use have logged in, and a username or userid variable ($_SESSION['user']) where you can save which user that browser is authenticated as.

Categories