Skip to content

[BUG] ZorxAuth: Remember Me duration is lost on the SSO gateway redirect to the session-set URL #1315

Open

Description

@Vincent4252

Describe the bug

ZorxAuth's "Remember Me" checkbox only affects the first, interactive login. Whenever the user is already authenticated at the auth gateway (the "skip the login step" fast path), the gateway redirects to the session set URL without the remember_me parameter. The visited host therefore issues zr_xauth_session with the plain Cookie Duration and thereby overwrites a previously issued long-lived cookie on that host. Net effect: "Remember Me" seems to be ignored and sessions fall back to Cookie Duration.

This is not a version-specific bug and upgrading does not help. I verified on current main: the fast-path redirect in handleAuthPage is byte-identical to the code quoted below, and none of the commits that touched gateway.go / routers.go after the module was introduced changed the remember-me handling (last check: v3.3.5-rc1, merged 2026-09-16). All line numbers below refer to current main; the stable release numbers are given in brackets for reference. The module itself was added in v3.3.2-rc2 (PR #1055) - that is only the reporter's deployment, see the host environment section. I could not find an existing issue/PR/discussion covering this.

To Reproduce

Setup: Zoraxy Auth with Auth Gateway enabled, two protected hosts using the same SSO (e.g. app-a.example.com, app-b.example.com).

  1. Open app-a.example.com, log in and check "Remember Me".
  2. DevTools → Application → Cookies → zr_xauth_session on app-a.example.com: Max-Age equals the configured "Cookie Duration (seconds) - Remember Me" value (e.g. 34560000). Correct so far.
  3. Open app-b.example.com in the same browser (no cookie for that host yet; gateway cookie is still valid) → the gateway takes its fast path.
  4. DevTools on app-b.example.com: the redirect is
    …/.wellknown/zorxauth/session/set?session_id=…&redirect=… - remember_me is missing, so the resulting zr_xauth_session has Max-Age = Cookie Duration (e.g. 3600).

The same happens on a host the user has visited before, as soon as its cookie is gone while the gateway cookie is still valid (delete only the app cookie, keep the gateway cookie, reload): the host cookie is re-issued with the short duration.

Expected behavior

"Remember Me" should apply to every session-set redirect, not just to the interactive login. The session cookie of the visited host should get Cookie Duration (seconds) - Remember Me.

Screenshots

N/A - the effect is visible in Browser DevTools (Application → Cookies → zr_xauth_session → Max-Age per host).

Browser (if it is a bug appears on the UI section of the system):

  • OS: Windows 10
  • Browser: Google Chrome
  • Version: 153.0.8010.53

Host Environment (please complete following information, DO NOT REMOVE ANY FIELD(S)):

  • Arch: amd64
  • Device: VPS
  • OS: Debian 13
  • Version: 13 (trixie)
  • Are you using Docker? (yes / no): no
  • Docker Version (fill in "N/A" for native deployment): N/A
  • Zoraxy Version: 3.3.2 (deployment I reproduced it on; the same code path is present in v3.3.5-rc1 / main)

Supplementary links

#1055 (v3.3.2-rc2, introduced the ZorxAuth SSO module)

Additional context

Root cause - only the interactive login path forwards the flag:

  • the login page (POST /login → auth.html) builds sessionSetURL?session_id=…&redirect=…&remember_me=<data.rememberMe> and works.
  • the gateway fast path (already authenticated at the gateway) builds the redirect server side and never carries it:
// src/mod/auth/sso/zorxauth/gateway.go, handleAuthPage
// main / v3.3.5-rc1: line 250    [stable v3.3.2: line 220]
sessionSetURL := fmt.Sprintf("%s://%s/%s?session_id=%s&redirect=%s",
    targetProtocol, hostWithPort,
    strings.TrimPrefix(gs.router.Options.SSOSessionSetURL, "/"),
    sessionId, url.QueryEscape(redirectURL))
// src/mod/auth/sso/zorxauth/routers.go, handleSessionSetCallback
// main: line 144    [v3.3.2: line 148]
rememberMe := strings.EqualFold(r.URL.Query().Get("remember_me"), "true") || r.URL.Query().Get("remember_me") == "on"
cookieDuration := ar.Options.CookieDuration
if rememberMe { cookieDuration = ar.Options.CookieDurationRememberMe }

…so rememberMe is false and MaxAge: cookieDuration (routers.go - main: line 180 [v3.3.2: line 184]) writes the short duration into the host cookie (same cookie name, same host → overwrite).

In addition, the fast path renews the gateway session with the plain CookieDuration (gateway.go - main: line 229 [v3.3.2: line 199]), because GatewaySession does not store the flag at all:

type GatewaySession struct {
    Username string
    Expiry   time.Time
}

Related observations in the same code path:

  • handleLogin has no fallback for cookie_duration_remember_me <= 0 while handleSessionSetCallback does (routers.go - main: line 149 [v3.3.2: line 153]). With 0, the gateway writes MaxAge: 0 (plain session cookie) and time.AfterFunc(0, …) (gateway.go - main: line 451 [v3.3.2: line 390]) removes the session from the store immediately → the user is bounced back to the login page. The admin UI would still show the default 604800 (settings.go - main/v3.3.2: lines 26-28).
  • The passkey login path (passkey.go - main: line 479) never reads a remember-me flag, so passkey logins can only ever get the short duration.
  • For the record, the cookie itself is written as Max-Age = <configured seconds> (no Expires, no scaling), so 2592000 yields exactly 30 days in Chromium - the browser side is not the problem; Chromium caps at 400 days.

Suggested fix: store the flag in the gateway session and reuse it for the renewal and for the session-set redirect (GatewaySession.RememberMe bool, set in handleLogin, then ...&remember_me=%t", …, rememberMe in the fast path).

Workaround until then: set Cookie Duration to the desired long value, since the fast path always uses that one.

I have a working patch for current main (applies with git apply -p1; go build / go vet / gofmt clean, plus a regression test asserting remember_me=true in the fast-path redirect). Happy to open a PR if you would like it fixed that way - just say the word.

zoraxy-fix-remember-me-zoraxy-main.patch

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions