Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(session): Replace remember-me tokens in transaction #40628

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ChristophWurst
Copy link
Member

Summary

Running delete from oc_preferences where … in two READ COMMITTED transactions makes the database serialize the operation and allow detection of a second DELETE that happened concurrently.

This is not a real fix but it can help us get a better insight into the problem.

TODO

  • Improve token rotation
  • Adjust unit tests

Checklist

*/
$newToken = $this->atomic(function() use ($uid, $currentToken): ?string {
// get stored tokens
$tokens = $this->config->getUserKeys($uid, 'login_token');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

food for thought: we might be able to skip the SELECT and go for the DELETE directly

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you doing the select so you have that explict? As to ensure no database funny buisness goes on when you do a delete+insert in the transaction?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the DELETE and INSERT should not trigger a conflict, even in concurrent situations, because the unique contraint is on appid and configkey. configkey is the new, random token.

only in theory there might be two processes with the same random token ;-)

@ChristophWurst ChristophWurst added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Sep 26, 2023
}, $this->connection);

// Token verification or replacement failed. Session can't be revived.
if ($newToken === null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if the transaction aborts it just defaults to null? Or is there an exception that needs handling somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the transaction commits. only unhandled exceptions inside the closure cause a rollback.

null means either SELECT found no results or DELETE did not hit any rows

* @param string $key the key under which the value is being stored
*/
public function deleteUserValue($userId, $appName, $key) {
public function deleteUserValue($userId, $appName, $key): bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this in general 👍

@solracsf solracsf added this to the Nextcloud 28 milestone Oct 27, 2023
@skjnldsv skjnldsv mentioned this pull request Nov 1, 2023
@blizzz blizzz mentioned this pull request Nov 6, 2023
@ChristophWurst ChristophWurst removed this from the Nextcloud 28 milestone Nov 7, 2023
@ChristophWurst ChristophWurst added 1. to develop Accepted and waiting to be taken care of and removed 2. developing Work in progress labels Nov 7, 2023
@solracsf solracsf added this to the Nextcloud 28 milestone Nov 21, 2023
@blizzz blizzz mentioned this pull request Nov 22, 2023
5 tasks
@ChristophWurst ChristophWurst removed this from the Nextcloud 28 milestone Nov 22, 2023
@blizzz blizzz added this to the Nextcloud 29 milestone Nov 23, 2023
@skjnldsv skjnldsv added 2. developing Work in progress and removed 1. to develop Accepted and waiting to be taken care of labels Feb 21, 2024
This was referenced Mar 12, 2024
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
@ChristophWurst ChristophWurst force-pushed the fix/session/transactional-remember-me-renewal branch from 455aee3 to 908c381 Compare March 14, 2024 14:05
'uid' => $uid,
'user' => $uid,
]);
return false;

Check failure

Code scanning / Psalm

FalsableReturnStatement Error

The declared return type 'null|string' for /home/runner/actions-runner/_work/server/server/lib/private/user/session.php:926:26323:-:closure does not allow false, but the function returns 'false'
This was referenced Mar 18, 2024
@skjnldsv skjnldsv modified the milestones: Nextcloud 29, Nextcloud 30 Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🏗️ In progress
Development

Successfully merging this pull request may close these issues.

None yet

5 participants