If a Joomla user account has been compromised and is logged in and being used on a different computer, changing the password does not help to log the attacker out. It would be nice to force a session change and/or user logout after a password change.
I use the DB for sessions and I could solve it with a plugin and the onUserAfterSave
function, which would delete all sessions in the DB where user id is X and session id not is the current session id. But I thought posting this here first, maybe this should be integrated in Joomla?
Joomla version: 3.8.6
PHP: 7.1
MySQL: 5.6
This bug was reported to us by a security researcher.
Labels |
Added:
?
|
Status | New | ⇒ | Discussion |
Category | ⇒ | Authentication |
Yes, I understand it is possible to logout a user manually, but that is not the issue. We have a site with millions of hits every hour and over 100.000 registered users. I am not looking to manually logout users, I need to implement automatically logout on password change. Please read the posted issue carefully.
(it you have such a busy site you really must upgrade the version of php. PHP 7.* is considerably faster)
This shouldn't be an arbitrary core functionality. As you pointed out, a simple plugin listening to onUserAfterSave
can handle this.
There is one issue in your approach if not using the database session handler. It won't actually destroy the session, just the optional metadata record. You need something like this to ensure all sessions are destroyed:
$query = $this->db->getQuery(true)
->select('session_id)')
->from('#__session')
->where($this->db->quoteName('userid') . ' = ' . (int) $user['id']);
if (!$sharedSessions)
{
$query->where($this->db->quoteName('client_id') . ' = ' . (int) $this->app->getClientId());
}
try
{
$sessions = $this->db->setQuery($query)->loadColumn();
}
catch (JDatabaseExceptionExecuting $e)
{
return false;
}
$handler = JFactory::getConfig()->get('session_handler' , 'database');
$storage = JSessionStorage::getInstance($handler);
foreach ($sessions as $session)
{
$storage->destroy($session);
}
Status | Discussion | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-03-26 12:17:41 |
Closed_By | ⇒ | feltkamptv |
I will implement this then with a plugin. Thanks again for the fast response!
I am now using this code in my user plugin and it seems to work:
public function onUserAfterSave($user, $isnew, $success, $msg)
{
if(!empty($user['password_clear']) && !$isnew){
$session = JFactory::getSession();
$session_id = $session->getId();
$query = $this->db->getQuery(true)
->select('session_id')
->from('#__session')
->where($this->db->quoteName('userid') . ' = ' . (int) $user['id'])
->where($this->db->quoteName('session_id') . ' != ' . $this->db->quote($session_id));
try{
$sessions = $this->db->setQuery($query)->loadColumn();
}catch (JDatabaseExceptionExecuting $e){
return false;
}
if(count($sessions) > 0){
$handler = JFactory::getConfig()->get('session_handler' , 'database');
$storage = JSessionStorage::getInstance($handler);
foreach($sessions as $session){
$storage->destroy($session);
}
}//count sessions
}//if not new and password changed
return true;
}
If this would be implemented, what if both the 'compromisor' and you are logged into the same account? The compromisor changes the password, your session will be aborted and you won't be able to log in...
Or do I miss something?
PS: Sorry for commenting on this old thread.
If this would be implemented,
it is not implemented ;)
Or do I miss something?
You are correct this would be the case where should joomla know who is compromisor and the original user? ;)
I would like to kindly ask to reconsider this decision.
OWASP clearly states to renew the session ID after a password change: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#renew-the-session-id-after-any-privilege-level-change
It is also not a very costly thing to do. Usually, it is 1–2 lines of code and has no effect on the user experience.
For a detailed discussion on the matter, also check out https://security.stackexchange.com/questions/266777/session-regeneration-after-password-change
You can force a user to be logged out by clicking on the X next to their name in the logged in users module present on your admin dashboard