Close a Session Upon Account Deletion - php

Many websites I've created have user data stored in sessions for quick access. The problem is that if an Administrator chooses to delete or disable a user's account, as long as they have their session cookies they're still technically "logged in."
While there are a few workaround solutions, such as making a database check on the user before they make any changes or adding a database check into the logged in verification function, these are less efficient than I would like.
So my question is, is there a way to close a session for a user from another user based on data stored in said session, like a user ID? If not, when would it be considered insecure to use session data internally, without database verification?
I should note that this question is asked under the assumption that I will be using the built-in $_SESSION variable, not some sort of custom database implementation, since a database session would be fairly easy to track down.
I'm trying to avoid using a database since keeping session data on the local server is far more efficient than adding the latency of connecting to an external database every time I want to access session data.

Try using the following achieve what you are looking for:
Getting all the sesssions: $_SESSION List in PHP
How to kill a particular session: How to destroy a specific PHP session

Have you tried session_destroy?
Session Destory

You can use session_destroy at the end of the process, but furthermore:
In order to kill the session altogether, like to log the user out, the session id must also be unset [and] then the session cookie must be deleted.
As a side note: one 'good' thing about PHP documentation is you're absolutely, like, guaranteed a laugh.

You can't destroy session on someone else his computer... . If you really want to do it, you should check on every page if the account is still available.. Or some other workaround.. .

Related

Is it possible to prevent php session from destroying when you close browser?

We want to use sessions instead of cookies for keeping track of a few things. However, when I close my browser, and I reopen a page to echo a session var, it doesn't exist (which is how it is suppose to be). Is it possible to prevent this from happening with some magic or anything?
This is not a duplicate question, all I see are people wanting to destroy sessions, I want to do the opposite and retain the session for as long as possible.
Any knowledge would be appreciated.
The right way of doing this is with a database, you can mimic or control php sessions and store them in a database instead of in a file ( as normal ). Then once you have control of the data you can base renewing session via the ip address or better yet by login.
So say a user logs in and then you need to store some data, you store that in the session but php will store it in your database table ( when configured correctly ). Latter the user comes back, initially any visitor would get a fresh session, however once they login you would be able to retrieve the past session they had. You generally don't have much control on if or when a client will delete expired cookies.
This topic is too extensive to put just a few pieces of example code but I did find this small article on the topic.
http://culttt.com/2013/02/04/how-to-save-php-sessions-to-a-database/
The guts of it is to use this function, session_set_save_handler
http://php.net/manual/en/function.session-set-save-handler.php
Once you have control of the data you can do whatever you want, however I would caution you about relying only on the IP address and it would be preferable to use a login system for something like this to prevent serving the session up to the wrong visitor.
You cannot reliably control what happens on the client side, even using a separate cookie would not be reliable and would have the disadvantage of storing data on the client where it could be accessed instead of keeping it on your server. Sessions are controlled by cookies but the data in them remains on your server, the cookie just identifies the client.
As a side note, I personally dislike using sessions at all. It may be possible to store what you need in the url, then it can be bookmarked. The classic example would be input for a search form ( via $_GET ) or for paging purposes. There is nothing wrong with doing this if it's not secure data. The problem with sessions is if the data is for a page such as my "classic example" or for paging you get only one session, so you would only be able to have one set of search data at a time, in the url you could have several sets of search data open at once. That said it does largely depend on what you need to save or persist.
Reset the session cookie manually.
$lifetime=60*60; // duration in seconds
session_start();
setcookie(session_name(),session_id(),time()+$lifetime);
You can use session.gc_maxlifetime and session_set_cookie_params, i.e.:
// server should keep session data for AT LEAST 1 Year
ini_set('session.gc_maxlifetime', 3600 * 24 * 365);
// each client should remember their session id for EXACTLY 1 Year
session_set_cookie_params(3600 * 24 * 365);
session_start();
Note:
You can also change the session options globally by editing php.ini -
Session configuration options
PHP sessions use session cookies. Browsers have their own ways of dealing with them but they all consider them to be trash if you close the browser.
Session cookies are not and can not be made persistent. If you need persistent cookies, just use a regular cookie to save a user identification code that your server would recognize, and save their session information in a database or flat file indexed on that id code.
Note that accumulating sessions on the server progressively causes important performance and security concerns.
Note on other answers: All of them mention ways to extend the session cookie expiration which will not overcome the regular behavior when you close your browser window.

Conceptual understanding of PHP server session

So as a engineer, I usually require a concert understanding to be able to work with something. I feel like I understand the basics of a session. I am wondering about the specifics and details there of.
What are the limitations of a session?
How can I manipulate a session? What can explicitly not be done to or with a session.
What data structures does PHP use to define and manage sessions?
Is a PHP session different from any other session in any significant way?
I understand that these questions are general, so if anyone can simply suggest a good resource I would be thankful. There is plenty of info out there, but it is either too basic or teaching to a specific topic.
Thank you for the help.
Sessions is a way for the server to recognize you so he sends to you a customized version of the page instead of sending always the same page for everybody.
To recognize you one way is he tells the browser to save in your computer a small file with a simple text, and when you visit the page again the server would ask the browser for that file, if the browser sends it, and it contains the expected content, the server can now know this is you again. That are cookies.
Another way to maintain a session, a part from cookies, is the server puts a special unique token for you in the url of all the links the page has. Whenever you browse the site all pages you visit will have that token, the server see it and know it's the token it made to you, so he knows it's you again.
So both with cookies or url-based sessions, the server will have to save info about the sessions opened, for example to store the $_SESSION variables you create in PHP, if you create such a variable the server will save it to a file which he will later identified by your cookie or token content and when you re-visit the page he will read that file and load the $_SESSION variables you create last time.
Here's a good resource: http://php.net/manual/en/book.session.php
What are the limitations of a session?
I don't really know what you mean by that. Limitations in what context?
How can I manipulate a session?
To manipulate values, just use the $_SESSION superglobal directly.
What can explicitly not be done to or with a session?
Again, without context, it's hard to understand what you mean. I guess an important point is that sessions are transient, so you can't explicitly store data you want to keep indefinitely.
What data structures does PHP use to define and manage sessions?
The filesystem.
Is a PHP session different from any other session in any significant way?
What is another session?
http://php.net is the best source for your questions
PHP session is a very nice way of having persistent information on your site for different users.
Check out the PHP session functions you can use.
You can view examples of how to use sessions at php.net.
A session is most commonly associated with user accounts. A user can log into your site, and you create a user session to keep track of their information and make sure they are allowed to be logged in.
The basic assumption is that a session is secure, because the server is aware of the sessions in progress. Utilizing sessions over HTTPS is a fairly secure way of keeping users logged into your site (without HTTPS you run the risk of session hijacking).
The other basic function is to have persistent data about a given user. So let's say you wanted to keep track if the user has submitted a form, you could do:
$_SESSION['form_submitted'] = TRUE;
And now you can check that global variable whenever you want to know if that specific user has submitted the form. So the session (in the same way a cookie is used) allows you to do really cool things that otherwise would not be possible.

Storing user session variables in file vs in database

I've got a php application and I'm saving the session variables for the user using $_SESSION itself. Is there any particular advantage of storing it in a database?
I'm looking for a reliable / well-researched article which talks more about this. I havent been able to locate anything yet.
The advantage you have of storing it in a database is that the data exists as long as you want it to exist.
Your browser will destroy the session according to how it is setup, which makes it a bit unreliable. I can't however find an article on this yet but this is what I use as a convention for a situation like this.
Any data that needs to be stored long term, like user details and activity I store in a database. Any data that is only relevant to the current workspace, like logging into a site and posting a few comments etc. can be stored in the session. For instance I store user authentication details in a session to constantly check whether the user is logged in or not and whether to redirect him/her to the correct page.
This works wonders when checking access rights throughout your application.
For me its much safer to store user details in a database because it cannot be publically accessed like the $_SESSION.
Please disagree with me if you want to though.
I would say storing in database is better.Because
When you are hosting your site with a shared host
PHP uses the same path for storing sessions for all the users,somewhere that is not in your folders.
You can track the users and their status easily.
For application that are running on multiple servers, you can store
all the session data in one database.
This article may help.
Well this is a question for the ages. Personally from what I have learned in my time. Unless your site starts booming on a massively large scale where you need to start using multiple servers for various aspects of the system such as load balancing where you have many mirror systems running. Or need to improve performance a little for an over populated system the benefits of using DB related sessions or File based sessions really isn't any different.. Grant it I could be wrong this is merely my own personal perception off my own experiences. Just like you Ive never really found any articles, posts, other that really put either to the test side by side hell I don't even think I have found anything that really puts either to the test stand alone for that matter. Personally I just go with what ever the need is (or desire of my client) usually I just stick to native sessions file based.
I hear they can be spoofed, but have seen no proof to that notion to date. So other than that potential I stick with file based. Unless I am using a system like code igniter then sessions seem to handle better DB driven with it rather than not.
At some point in time you're going to have to store something in a session. Whether it's all the session variables or just the ID of a row in a sessions table. That being the case it would be fairly easy to alter the ID stored in a badly encrypted session and hijack a different session.
Consider this:
Full Session Option. This has the User ID, Username and an encrypted and hashed password stored so that every time a page is called it verifies my login. To hijack someone else's session I'd have to know their User ID, Username and Password Hash and be able to overcome the sessions inherent encryption.
Session + DB Option. This just has a Session ID stored that references a row in a database. All I have to do to change the session I want is to break the encryption on the session and say add one to the Session ID. I'd then be authenticated as the user that logged in after me.
You could store login details in a session and then any none login related data in a session table if you have a lot of extra information but then again you might as well just remove the need for an extra table and extract the data from whatever relevant tables you need.
From my short experience, you should store in $_SESSION only data that you will NOT need to be refreshed in all sessions opened by a unique user in different devices.
(mobile/desktop/etc.)
In other words, data that you are sure will never change like a userID.
For example, I had stored the user profile picture path into
$_SESSION and it led to a strange User Experience. When changing the
profile picture in a desktop, it did not refresh the profile picture
for the user on his mobile. Other users saw the new picture though.
Indeed, the path was refreshed into the DB but not in the $_SESSION.
Login-out and Login-in would not change anything.
Remember that the default behavior is that $_SESSION passed with cookie will be different for each browser even if this is the same user logged in. You will have to do a session_destroy() to avoid being stuck with old data.
Very temporary data may be stored in $_SESSION as well I guess.
NB: the basic need of global session, out of these arguments, is to have variables available globally

Create PHP session for all users or only ones who want to log in?

At the moment my CMS creates a PHP session for every user who visits the site. I'm thinking about only creating a session for users who want to log in. The problem I have here is that some UI elements for logged in users are on all pages, so on every page request the system has to check if the user is logged in, which means I have no other option to start a session on every page request? Or am I wrong? Is it normal practise to create a session for every user, even if dose not want to log in?
Short, I'd like to know if A. there is an option in my use case to only create a PHP session for users who want to log in and B. if it consider bad practise creating a session for every user, regardless if he wants to log in or not. If this isn't the case, I can leave things as they are really ...
You have no (real) choice. You can not know, that a user is logged in (or not) without a session.
Quick answer:
In your use case, it is perfectly fine to create a session for every user. Sessions are negligible and not something to worry about as far as performance goes (in your case).
The method you're using is not bad practice at all. In fact I'd say it's pretty near best practice.
Long answer:
In my 6+ years of experience as a PHP programmer in the corporate world, it is perfectly normal to create a session for every user, regardless of whether or not they're logged in. In fact, sessions can be used to do a lot of convenient features for a user even when they're not logged in -- such as shopping carts, etc. You're doing things right. If you want to speed up performance at all, use a tool like Google's Pagespeed and Yahoo's YSlow -- they'll give you tips on best practice for websites.
It is possible to avoid creating a session every time. So what if session files are small? Why proliferate them when it's unnecessary?
This is what I do, in essence:
Check for the existence of the session cookie on the incoming request, and only do the session_start() if you've received one.
Logged-out users browsing the site (typically) won't be sending the session cookie, and so they won't trigger a session_start(). Simple.
Once someone logs into your site and you do want to start a session (session both logically in your application and in the PHP sense) then use session_start() etc which will handle setting up the cookie.
And once someone logs out, make sure you destroy the session cookie too, not just the PHP session itself.
Obviously the user could block your cookie operations at their end and screw things up, but they could do this anyway.
Can't you just look for an empty $_SESSION value to see if they're logged in?
In most cases, logins are managed via the session, therefore you must create a session at the start of the page to determine if they are logged in or not. You have no choice really... It is not bad practise, it is common practise.

How to re-initialize a session in PHP?

I am attempting to integrate an existing payment platform into my webshop. After making a succesful transaction, the payment platform sends a request to an URL in my application with the transaction ID included in the query parameters.
However, I need to do some post-processing like sending an order confirmation, etc. In order to do this, I'd need access to the user's session, since a lot of order-related information is stored there. To do this, I include the session_id in the intial request XML and do the following after the transaction is complete:
$sessionId = 'foo'; // the sessionId is succesfully retrieved from the XML response
session_id($sessionId);
session_start();
The above code works fine, but $_SESSION is still empty. Am I overlooking something or this simply not possible?
EDIT:
Thanks for all the answers. The problem has not been solved yet. As said, the strange thing is that I can succesfully start a new session using the session_id that belongs to the user that placed the order. Any other ideas?
Not really what you ask for, but don't you need to persist the order into database before you send the customer to the payment-service? It's better to rely on persisted data in your post-processing of the order when you receive the confirmation of the payment.
Relying on sessions is not reliable since you will have no idea on how long this confirmation will take (usually it's instant, but in rare cases this will have a delay).
Also, in the event of your webserver restarting during this time span, will make you lose relevant data.
A third issue is if you have a load-balancing solution, with individual session-managment (very common) then you will have no guarantee that the payment-server and your client will reach the same webserver (since stickiness is usually source-ip based).
I will venture to guess that since domains are different from where the session is set to where you are trying to read it, php is playing it safe and not retrieving session data set by a different domain. It does so in an effort to preserve security in case somebody were to guess session ID and hijack the data.
Workaround for this, assuming the exchange happens on the same physical disk, is to temporary write order data to a serialized (and possibly encrypted depending on wether or not full credit card number is being tracked, which is a whole another story) file that once read by the receiving end is promptly removed.
In essence all that does is duplicates the functionality that you are trying to get out of sessions without annoying security side-effects.
Many thanks for all the replies.
Smazurov's answer got me thinking and made me overlook my PHP configuration once more.
PHP's default behaviour is not to encrypt the session-related data, which should make it possible to read out the session data after restarting an old session from another client. However, I use Suhosin to patch and prevent some security issues. Suhosin's default behaviour is to encrypt session data based on the User Agent, making it a lot harder to read out other people's sessions.
This was also the cause of my problems; disabling this behaviour has solved the issue.
Make sure you're closing the current session before you attempt to start the new one. So you should be doing:
$id = 'abc123';
session_write_close();
session_id($id);
session_start();
Dirty, but has worked for me:
Tell the payment gateway to use
http://yourdomain.com/callbackurl.php?PHPSESSID=SESSIONIDHERE
PHP uses that method of passing a session around itself if you set certain config vars (session.use_trans_sid), and it seems to work even if PHP has been told not to do that. Its certainly always worked for me.
Edit:
Your problem may be that you have session.auto_start set to true - so the session is starting automatically using whatever ID it generates, before your code runs.
How about do it in another PHP page, and you do a iframe include / redirect user to the second page?
I'm not sure the exact length of time between your transaction and your check; but it certainly seems that your session cookie has expired. Sessions expire usually after 45 minutes or so by default. This is to free up more uniqid's for php to use and prevent potential session hijacking.
I'm not sure if you have a custom session handler and whether it's stored in the database but guessing from your posts and comments on this page I would assume it is stored in server side cookies.
Now the solution to your problem, would be to bite the bullet and store the necessary data in the database and access it via the session id, even if it means creating another table to sit along side your orders table.
If however you are doing the action immediately then the other explanation is that either the user logged out or committed an action which destroyed their session (removing the server side cookie).
You will see these cookies in your servers /tmp folder, try have a look for your cookie, it should be named 'sess' + $session_id.

Categories