fix(auth): issue a Secure session cookie under the __Host- prefix

A cookie named healthlog_session can be set by any host under the same
registrable domain, so a page on a sibling subdomain could plant a session of
its choosing in a visitor's browser. Wherever the session cookie is Secure it
is now issued as __Host-healthlog_session, which a browser accepts only from
this exact host. Plain-HTTP installs, which cannot hold a __Host- cookie,
keep the old name.

Nobody is signed out: the old name is still read after the new one, a
session found under it is re-issued under the new name and the old cookie
expired, and a browser holding the new cookie is never answered from the old
one. Every reader and writer goes through one module, which the proxy, the
native-caller check, the native handoff and the OIDC callback use; the
session-surface guard follows the new reader.
This commit is contained in:
Marc-André Bombeck committed 2026-10-25 17:44:31 +01:00
1 parent d3257a1b6b
commit 5a875d2840
19 files changed
+348 -88

No files matched your search

+2 -2
View File
@@ -1,5 +1,6 @@
import { NextResponse, type NextRequest } from "next/server";
import { shouldRunWeb } from "@/lib/process-type";
import { readSessionCookie } from "@/lib/auth/session-cookie";
import {
findRetiredRoute,
retiredRouteEnvelope,
@@ -560,8 +561,7 @@ export function proxy(request: NextRequest) {
// can never be session-gated without also being uncacheable.
const isSessionGatedPage = !isApiRoute && !isStaticFile && !isPublic;
if (isSessionGatedPage) {
const hasSession = request.cookies.has("healthlog_session");
if (!hasSession) {
if (!readSessionCookie(request.cookies)) {
return applyBaselineSecurityHeaders(
NextResponse.redirect(new URL("/auth/login", request.url)),
);