From 725f5bea3f1dcd9dc9941a9cb1b84922f6088742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Tue, 7 Apr 2026 12:26:54 +0200 Subject: [PATCH] fix: Reduce the mixups between apptokens and session ids MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- lib/private/User/Session.php | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 811c5ba4bc326..651d5e8f9c42b 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -394,6 +394,12 @@ public function logClientIn($user, try { $dbToken = $this->getTokenFromPassword($password); $isTokenPassword = $dbToken !== null; + if (($dbToken instanceof PublicKeyToken) + && !in_array($dbToken->getType(), [IToken::PERMANENT_TOKEN,IToken::ONETIME_TOKEN]) + ) { + // Refuse session tokens here, only app tokens and onetime tokens are handled + return false; + } } catch (ExpiredTokenException) { // Just return on an expired token no need to check further or record a failed login return false; @@ -817,6 +823,7 @@ private function validateTokenLoginName(?string $loginName, IToken $token): bool */ public function tryTokenLogin(IRequest $request) { $authHeader = $request->getHeader('Authorization'); + $tokenFromCookie = false; if (str_starts_with($authHeader, 'Bearer ')) { $token = substr($authHeader, 7); } elseif ($request->getCookie($this->config->getSystemValueString('instanceid')) !== null) { @@ -824,6 +831,7 @@ public function tryTokenLogin(IRequest $request) { // session and the request has a session cookie try { $token = $this->session->getId(); + $tokenFromCookie = true; } catch (SessionNotAvailableException $ex) { return false; } @@ -831,18 +839,23 @@ public function tryTokenLogin(IRequest $request) { return false; } - if (!$this->loginWithToken($token)) { + try { + $dbToken = $this->tokenProvider->getToken($token); + } catch (InvalidTokenException $e) { + // Can't really happen but better safe than sorry return false; } - if (!$this->validateToken($token)) { + + if ($dbToken instanceof PublicKeyToken && $dbToken->getType() === IToken::TEMPORARY_TOKEN && !$tokenFromCookie) { + // Session token but from Bearer header, not allowed return false; } - try { - $dbToken = $this->tokenProvider->getToken($token); - } catch (InvalidTokenException $e) { - // Can't really happen but better save than sorry - return true; + if (!$this->loginWithToken($token)) { + return false; + } + if (!$this->validateToken($token)) { + return false; } // Set the session variable so we know this is an app password