From: Tim Düsterhus Date: Tue, 16 Mar 2021 13:54:48 +0000 (+0100) Subject: Limit the number of active sessions per user X-Git-Tag: 5.4.0_Alpha_1~148^2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=1c2d2cfbdb0d1a690960165b606bc5fe19431d68;p=GitHub%2FWoltLab%2FWCF.git Limit the number of active sessions per user --- diff --git a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php index db3fb09f4e..caa5929e42 100644 --- a/wcfsetup/install/files/lib/system/session/SessionHandler.class.php +++ b/wcfsetup/install/files/lib/system/session/SessionHandler.class.php @@ -134,6 +134,8 @@ final class SessionHandler extends SingletonFactory private const USER_SESSION_LIFETIME = 60 * 86400; + private const USER_SESSION_LIMIT = 30; + private const CHANGE_USER_AFTER_MULTIFACTOR_KEY = self::class . "\0__changeUserAfterMultifactor__"; private const PENDING_USER_LIFETIME = 15 * 60; @@ -1032,6 +1034,28 @@ final class SessionHandler extends SingletonFactory $this->sessionID, ]); + // ... delete any user sessions exceeding the limit ... + $sql = "SELECT all_sessions.sessionID + FROM wcf" . WCF_N . "_user_session all_sessions + LEFT JOIN ( + SELECT sessionID + FROM wcf" . WCF_N . "_user_session + WHERE userID = ? + ORDER BY lastActivityTime DESC + LIMIT " . self::USER_SESSION_LIMIT . " + ) newest_sessions + ON newest_sessions.sessionID = all_sessions.sessionID + WHERE all_sessions.userID = ? + AND newest_sessions.sessionID IS NULL"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute([ + $user->userID, + $user->userID, + ]); + foreach ($statement->fetchAll(\PDO::FETCH_COLUMN) as $sessionID) { + $this->deleteUserSession($sessionID); + } + // ... and reload the session with the updated information. $hasSession = $this->getExistingSession($this->sessionID);