Search code examples
phpsessiondestroyread-write

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.


Solution

  • 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.