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.
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:Domainattribute (since Same-origin auth: host-only session cookie with uploads.sh as the front door and issuer #731 phase C/E;crossSubDomainCookiesdisabled), so it is never sent tostorage/store/embed/api/agents.uploads.sh.__Secure-— Better Auth applies this automatically in production; browser only accepts it over HTTPS.HttpOnly(JS can't read it),SameSite=Lax(+ Better Auth CSRF),Path=/.What
__Host-would addA
__Host--named cookie cannot carry aDomainattribute, 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.shserve untrusted bytes; see the stored-XSS note inapps/api/src/guards.ts) could plantSet-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:cookiePrefix: "__Host-better-auth"anduseSecureCookies: false(to stop the auto__Secure-prefix double-prefixing the name) anddefaultCookieAttributes: { secure: isProduction }to re-assertSecure;stack-rawoverhttp://127.0.0.1still work (__Host-/Secure cookies are rejected over http);apps/web/src/lib/auth-proxy.tsupdated and an audit that no plugin cookie (OAuthstate/PKCE, device, magic-link) uses a non-/path (which__Host-silently breaks);Fragile-across-upgrades workaround + forced re-login, for a narrow defense-in-depth gain, is a poor trade right now.
Revisit when
__Host-/host-prefix support — then it's a clean config change worth the one-time re-login; orAt that point the security rationale above still applies; this is a deliberate deferral, not a rejection.