Skip to content

SESSION_AUTH_NEXT lost during session rotation in _set_login_session #110

@ZechCodes

Description

@ZechCodes

Bug

The _set_login_session() function in skrift/controllers/auth.py clears the session for rotation but does not preserve SESSION_AUTH_NEXT, causing all ?next= redirect URLs to be lost after OAuth login.

Reproduction

  1. Visit https://example.com/auth/login?next=https://subdomain.example.com/
  2. Login page stores SESSION_AUTH_NEXT in the session
  3. Complete OAuth flow (click provider → authorize → callback)
  4. Expected: Redirect to https://subdomain.example.com/
  5. Actual: Redirect to / (the default)

Root Cause

In the OAuth callback (oauth_callback), the execution order is:

flash_success(request, "Successfully logged in!")
_set_login_session(request, login_result.user)       # ← session.clear() here

next_url = _get_safe_redirect_url(request, ...)       # ← SESSION_AUTH_NEXT is gone

_set_login_session calls request.session.clear() for session rotation, then only restores flash, flash_messages, and _nid. SESSION_AUTH_NEXT is wiped before _get_safe_redirect_url can read it.

Suggested Fix

Preserve SESSION_AUTH_NEXT across the session rotation in _set_login_session:

def _set_login_session(request: Request, user: "User") -> None:
    flash = request.session.get("flash")
    flash_messages = request.session.get("flash_messages")
    nid = request.session.get("_nid")
    auth_next = request.session.get(SESSION_AUTH_NEXT)  # ← add this

    request.session.clear()

    request.session[SESSION_USER_ID] = str(user.id)
    request.session[SESSION_USER_NAME] = user.name
    request.session[SESSION_USER_EMAIL] = user.email
    request.session[SESSION_USER_PICTURE_URL] = user.picture_url

    if flash is not None:
        request.session["flash"] = flash
    if flash_messages is not None:
        request.session["flash_messages"] = flash_messages
    if nid is not None:
        request.session["_nid"] = nid
    if auth_next is not None:                           # ← add this
        request.session[SESSION_AUTH_NEXT] = auth_next  # ← add this

Same issue exists in dummy_login_submit which follows the same pattern.

Impact

All ?next= redirect flows after login are broken. This affects any multi-domain setup (subdomains, external redirects) where the login page is on a different domain than the target.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions