Skip to content

Conversation

@86667
Copy link
Contributor

@86667 86667 commented Nov 13, 2025

Problem

See linked ticket for explanation of problem.

Changes

  • Server now generates GUID-based cookie names alongside legacy pubkey-named cookies for backward compatibility.
  • Improved the authorization layer to now evaluate all valid session cookies until one with the required capabilities is found. Before it would check the first with a valid session and return 403 if its capabilities didnt match, regardless of whether other cookies in the request may have the correct capabilities.
  • signout() will now remove all sessions belonging to the User
  • session() will return information about the first cookie in the headers list. This is the same behaviour as before. We will consider expanding on this functionality here

Limitations

The main difference here is that multiple Cookies for a single user is now supported. This means that we need to do a trip to the db for each to verify their secrets. Ive assumed that this will not be an issue since Cookie count is generally low. We may want to think about imropving this thought, eg:

  • Batch-get on DB for all sessions
  • Checking a session's capabilities before fetching the next one
  • Encoding a session's capabilities in the Cookie name - may have security implications?

@86667 86667 force-pushed the allow_multiple_cookies_per_user branch from df9a4c8 to 80cfd00 Compare November 13, 2025 17:51
@86667 86667 force-pushed the allow_multiple_cookies_per_user branch 5 times, most recently from c3f7e13 to db95665 Compare November 14, 2025 11:43
@86667 86667 force-pushed the allow_multiple_cookies_per_user branch from db95665 to dce5aa0 Compare November 14, 2025 12:29
@86667 86667 linked an issue Nov 14, 2025 that may be closed by this pull request
@86667 86667 force-pushed the allow_multiple_cookies_per_user branch from dce5aa0 to 764e6d2 Compare November 14, 2025 13:40
@86667 86667 marked this pull request as ready for review November 14, 2025 13:40
Copy link
Contributor

@SHAcollision SHAcollision left a comment

Choose a reason for hiding this comment

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

Looks like the test suite is failing because of clippy warnings. I anyway wonder whether it should succeed at all because as I understand create_session_and_cookie now sets the cookie path to capabilities.most_specific_scope() for both the new UUID cookie and the legacy public key cooki. For most apps that request /pub/<app>/... access, this path will look like /pub/<app>/. Browser cookie path rules mean that such a cookie will not be sent on requests to /session (or any other path outside that subtree). So I would expect that authenticated endpoints such as GET/DELETE /session can no longer see any cookies when hit from the browser, so session() and signout() will always fail with 401 right? The rust SDK keeps working because it manually injects the cookie header, but it bypasses browser semantics.

I don't know if there is any fix for this. Maybe setting path is not the best way to solve this issue to begin with. Maybe to preserve the filtering intent while keeping session endpoints working, we could attach an additional cookie scoped to /session, this one will suffer of the same bugs we've already seen in the current main codebase with chromium browsers...

Comment on lines +54 to +56
let sessions = sessions_from_cookies(&state, &cookies, pubky.public_key())
.await
.unwrap_or_default();
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, this converts every error, including database failures or internal errors, into “no sessions” and still returns 200 OK, right? The previous version returned the DB error to the client, so maybe is a regression in observability and correctness. Should propagate non-401 errors instead of unwrapping. For example, handle the unauthorized case explicitly and return Err(err) for everything else.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didnt want the failure of one session deletion to affect the deletion of the other sessions. Ive pushed code to awkwardly return the first error which it saw after attempting to remove all other sessions. I think this is the best we can do without introducing a regression?

@86667
Copy link
Contributor Author

86667 commented Nov 17, 2025

@SHAcollision The reason for setting Cookie.path to the same value as our Capability.path was to reduce the number of Cookies sent with each request, as we are now sending double the number that we were before.

If we can get away with that only by introducing another cookie for /session then it no logner provides us any efficiency gain! Reverted commit which sets Cookie.path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A user's cookie becomes invalid after creating a new cookie

3 participants