i have this question. My website is build whereby a user can only be in the member's page if he has login. therefore every page has this,
if (!$_SESSION['userid']) header index.php
Problem is that if i ban the user and the user did not end the session, he will still be allowed to use the site until he end the session and try to login again, and he will be denied due to the change in the status in the database.
I'm thinking that the only way is to delete the physical session file in the server, but i dont know how. Anyone?
What I have done is create a database query in a header file that is included in every page that either pulls the users profile or checks to see if they were banned. If so then I destroy their session.
What you need to do is add in your ajax post the user id, or some other information to identify the specific user posting. This way you can check on the server side if the user is allowed to post with each post, and if not take the necessary action.
Unless you're using the multi-level directory save method, something like this would probably be enough:
unlink(ini_get('session.save_path') . 'sess_' . $bannedSessionID));
check that your server's session files have the 'sess_' prefix, though. It could possibly be overridden somewhere. But in any case, by default all the session files are in a single directory (/tmp unless they've been moved) and can be opened/read/written/deleted by the webserver (as they have to be)
Related
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.
I'm currently using PHP sessions to keep track of user sessions, with a last-activity field for timeouts, an id field, and an account-type field. Currently, all of this information, as well as settings data, is pulled form a MySQL database and stored in the session once the user is logged in, and remains unchanged for the duration of the session.
The issue is that I wish to implement the ability for administrators to change users' account types remotely. If the user's account type is changed remotely while they're still logged in, the change in the database won't be reflected in the user's session variable.
One solution to this would be to add a logout_flag column to the users database table. When a user's account type is changed by an administrator, that user's entry in the database will have logout_flag set to 1. Then I can use a session script to check this entry on every page load, and log them out if it's set to 1.
My concern is that this would add too much overhead for the server; With hundreds of users logged in at the same time, this would amount to hundreds of MySQL queries per minute. Is this the ideal solution though?
Try with session_save_path(), with that function you can find the path where PHP saves all session files. You can delete the selected file with unlink() later.
Careful with this! If the path = the global /tmp directory. Other applications are using this directory also and you can break something.
You need to know also the session id of your user, maybe saving the token and the user id/name will help you to identify the correct session file.
I'm having a big trouble here: In my company we have a huge system and too many people access it every day. We are having the following problem:
User access his account on the pc A.
He goes to write his text
He write all his text but doesn't save it. Then open a new tab.
In the new tab, he access the account of his customer.
Using the account of his customer, he goes to write the customer's text.
After type the customer's text, he goes to the previous tab to save his own text and after save the customer text.
The two texts appears on the customer's page.
I was thinking in a way of the current screen store somewhere the actual session id, and then when the user click in a link, or post a form, the current page send the session id loaded when it was rendered to the requested page.
Can you help me please?
Thanks!
Its a little difficult to follow the use case specified, but it sounds like you need to check access rights to save 'text' to a particular account.
at the moment it appears that your authenticated customer account is saving to an account that isnt theirs?
for eg, in the new text method, before anything happens:
if($currentUserID != $accountOwnerID)
{
// throw a 403 exception here
}
this way if they happen to change identity during a session, their access rights will always be checked before anything else can happen.
The best solution is to use named sessions. See: session_name()
By using it, you can have different (and isolated) sessions which will not conflict to each other, even if in the same computer, same browser.
For your particular case, I would create a session named after the user logon, which is unique. That way, if user A logs in, he will have his own session. If a new tab is opened, and he logs as user B, a different session will be created, and both tabs will work simultaneously and correctly, each on it's own session space.
Just add session_name($UserLogon); before session_start(), should work good.
You can use session keys to check.
For that first you need to create a random session key and store it in a session variable. Also provide this value as a hidden element in your form. During the insertion you can check whether the value in hidden element is same as the session key, then insert. Else through error message. After successful insertion reset the session key again. It will overcome your problem.
Hope it helps.
I was just wondering. Lets imagine i have a website with a login-system in PHP. And if the user succesfully logs in to the system the php sets something like: $_SESSION['user']="Loggedin".
And now, if you as a user of the website, could you just create your own PHP-script in your XAMPP folder or whatever and set the session user to loggedin and get access to my site?
Thanks!
No need to worry for this,
If you use Cookie for this then there's issue to be hacked and son on. But in Session, it will store on server side, so whether user can create a file and used or trying to get data from buy using session variable, they can't.
User can't get Session variable from the local server, they must have to access session variable from the same server.
And one more thing, this session is destroys when you close your browser.
A PHP session stores user information on the server for later use.
So if you are making a session on your localhost, with the same name, that doesn't influence the one on the website/server.
Remember that session information is temporary and will be deleted after the user has left the website.
I've developed many login systems in PHP. Basically, for each website or application I created, it had a login scheme to create articles, upload images, edit comments e blablabla.
I've never had problems with that, except once when I created a kind of social page inside my website. There was a user bothering the other users, so I decided to delete his profile, that's why I'm here asking your help.
At the time, I was just checking the session on each page, for example:
<?php
if($_SESSION['loggedin'] === true)
{
// Keep that page
}
else
{
// redirect to login page
}
?>
Then, when I deleted his profile the session wasn't closed yet, after that the user continued annoying the other users, and I wasn't able to do anything.
So, what's the most common and best way to handle sessions on each page: Check the database each time or just check if the session is true?
I don't know whats the best way, but I do something like this:
I have an sql table with the sessions (for example userid, sessionid, expiredate, ...).
The sessionid is "saved" in a $_SESSION['cms_session'] .
If the sessionid which is in $_SESSION['cms_session'] doesn't exist in the session table, the user isn't loged in anymore.
For deleting the old sessions in the table i use crons.
What you are trying to do is have a single place where you can maintain user status and know that a change will be reflected immediately.
Checking a "user_status" field in the DB is a pretty efficient call to make on each request. This provides a single place where you know that if you deactivate a user, the changes will be reflected upon their next request. You can also do this easily without writing another set of routines to look through session variables or to create some sort of messaging system where the application announces that a user has been deactivated.
Checking the database each time a page loads is really inefficient. If all you're trying to do is kill his session, you should store sessions in memcached where the 'key' is based on the username, something like "johnsmith-session" and then on an admin page, send a message to memcached to kill that key, which should immediately log him out of your site.
If PHP is currently writing session data to disk, depending on how the data is serialized, you may be able to track down his session file on disk and delete that file, which will accomplish the same thing: the next time that user tries to load a new page, his session will be invalid and he'll be required to log in again.
Keep in mind that really persistent trouble users will often re-register a new account to continue their antics, so you'll want other means of watching for new registrations from that person.