fix: harden SSO ticket flow and revoke tickets on logout
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s

Reuse the outstanding auth_ticket instead of minting a fresh one on every
/client load, so reloading the page or opening a second tab no longer
invalidates a game session that is still connecting. New tickets are minted
with a guard against the previously-read value so concurrent launches
converge on the same ticket.

Revoke the auth_ticket when signing out (toolbar, header and sign-out
everywhere) so a leaked ticket can no longer be replayed against the
emulator, and prevent SSO leakage via referral by setting no-referrer on the
client iframe. Strip all whitespace from the ticket prefix and build the
launch URL through a tested helper that handles query strings, existing sso
params and URL fragments correctly.
This commit is contained in:
openhands committed 2026-08-29 20:54:06 +02:00
1 parent ca59a1065f
commit 7f39ba4257
7 files changed
+231 -28

No files matched your search

+2 -7
View File
@@ -2,11 +2,11 @@ import { count, eq, inArray } from "drizzle-orm";
import Image from "next/image";
import type { Session } from "next-auth";
import { getTranslations } from "next-intl/server";
import { signOutAndRevokeTicket } from "@/actions/sessions";
import { HeaderUserIdentity } from "@/components/header-user-identity";
import Link from "@/components/link";
import { RoomQuickEntry } from "@/components/room-quick-entry";
import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail";
import { signOut } from "@/lib/auth";
import { cached } from "@/lib/cache";
import {
db,
@@ -405,12 +405,7 @@ export async function TopHeader({ session }: { session: Session | null }) {
"color-mix(in srgb, var(--color-text-muted) 12%, transparent)",
}}
/>
<form
action={async () => {
"use server";
await signOut({ redirectTo: "/" });
}}
>
<form action={signOutAndRevokeTicket}>
<button
type="submit"
role="menuitem"