Skip to content

Defer __Host- session-cookie prefix (no native Better Auth support) #824

Description

@zachdunn

Deferred from #731 phase E, which listed the __Host- cookie prefix as an optional final step. On investigation it's not the clean flag the plan assumed, so we're holding it deliberately rather than shipping a workaround now.

Current state (already strong)

The production session cookie is __Secure-better-auth.session_token:

What __Host- would add

A __Host--named cookie cannot carry a Domain attribute, so a sibling subdomain cannot set/overwrite it for the apex origin. This closes one specific vector the current cookie does not: subdomain session fixation — an attacker with code execution on a user-content subdomain (storage/store/embed.uploads.sh serve untrusted bytes; see the stored-XSS note in apps/api/src/guards.ts) could plant Set-Cookie: Domain=uploads.sh; __Secure-better-auth.session_token=<attacker session>, shadowing the victim's cookie so the victim operates inside the attacker's session. __Host- prevents the subdomain from setting it at all.

Narrow but real: it requires a chained compromise (code-exec on a content subdomain) before it's exploitable.

Why it's held, not shipped

Better Auth (1.7.1 and current main) has no native __Host- support — the cookie writer only ever prepends __Secure- (or nothing); there is no __Host- toggle. Achieving it today is a workaround:

  • prod-gated cookiePrefix: "__Host-better-auth" and useSecureCookies: false (to stop the auto __Secure- prefix double-prefixing the name) and defaultCookieAttributes: { secure: isProduction } to re-assert Secure;
  • gated to production so dev / stack-raw over http://127.0.0.1 still work (__Host-/Secure cookies are rejected over http);
  • it renames every Better Auth cookie, so it also needs the hardcoded clearer in apps/web/src/lib/auth-proxy.ts updated and an audit that no plugin cookie (OAuth state/PKCE, device, magic-link) uses a non-/ path (which __Host- silently breaks);
  • and it forces a one-time re-login for every web user.

Fragile-across-upgrades workaround + forced re-login, for a narrow defense-in-depth gain, is a poor trade right now.

Revisit when

  • Better Auth ships first-class __Host-/host-prefix support — then it's a clean config change worth the one-time re-login; or
  • the user-content subdomain surface grows in a way that raises the fixation risk.

At that point the security rationale above still applies; this is a deliberate deferral, not a rejection.

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions