Skip to content

Sign out browsers whose session has already ended - #1624

Merged
RhysSullivan merged 2 commits into
mainfrom
fix/logout-unauthorized-stale-session
Aug 17, 2026
Merged

RhysSullivan merged 2 commits into
mainfrom
fix/logout-unauthorized-stale-session

Conversation

@RhysSullivan

Copy link
Copy Markdown
Collaborator

Signing out could answer with a raw {"_tag":"Unauthorized"} page instead of signing the browser out. Reported from the field.

Cause

logout was declared on CloudAuthApi, which carries .middleware(SessionAuth). A browser whose sealed session no longer authenticated at click time got the middleware's 401 before the handler ran. The console posts sign-out as a top-level form navigation (the WorkOS hop is cross-origin, so it can't be a fetch), so that error body was rendered as the page.

Nothing exotic is needed to reach it: a second open tab, a re-submit from history, or a session that expired or was revoked upstream while the tab sat open.

Change

Move the endpoint to CloudAuthPublicApi and read the sealed session off the request cookie. There is nothing to authorize — the request can only end the session whose cookie it presents — and the handler already fell back to / when the cookie wouldn't unseal.

Cookies are dropped only when the request actually presented one. Both are SameSite=Lax, so a cross-site form POST arrives bare, gets the redirect, and cannot be used to sign a user out.

Self-host is unaffected; it signs out through Better Auth.

Tests

e2e/cloud/logout-stale-session.test.ts — both scenarios fail on main with the reported body and pass here:

  • wire level: a stale session cookie is dropped and the browser is sent home; a cookie-less POST expires nothing
  • browser: two tabs open, sign out in one, then the other lands on the sign-in page instead of raw JSON

vitest run --project cloud cloud/logout-stale-session.test.ts cloud/auth-session.test.ts cloud/auth-hint.test.ts — 8 passed, including the existing "logout ends the AuthKit session upstream" and "logout clears the hint with the session" contracts. typecheck clean; vitest run src/auth in apps/cloud 73 passed.

Sign-out was declared on the session-authenticated API group, so a browser
whose sealed session no longer authenticated at click time got a 401 from
SessionAuth instead of being signed out. The console posts sign-out as a
top-level form navigation, so that error body was rendered as the page:
a screenful of {"_tag":"Unauthorized"}.

Move the endpoint to the public group and read the sealed session off the
request cookie. Nothing here needs authorizing — the request can only end
the session whose cookie it presents — and the handler already fell back to
"/" when the cookie would not unseal.

Cookies are dropped only when the request actually presented one, so the
now-public endpoint cannot be used cross-site to sign a user out.
@pkg-pr-new

pkg-pr-new Bot commented Aug 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

@executor-js/cli

npm i https://pkg.pr.new/@executor-js/cli@1624

@executor-js/config

npm i https://pkg.pr.new/@executor-js/config@1624

@executor-js/execution

npm i https://pkg.pr.new/@executor-js/execution@1624

@executor-js/sdk

npm i https://pkg.pr.new/@executor-js/sdk@1624

@executor-js/codemode-core

npm i https://pkg.pr.new/@executor-js/codemode-core@1624

@executor-js/runtime-quickjs

npm i https://pkg.pr.new/@executor-js/runtime-quickjs@1624

@executor-js/plugin-file-secrets

npm i https://pkg.pr.new/@executor-js/plugin-file-secrets@1624

@executor-js/plugin-graphql

npm i https://pkg.pr.new/@executor-js/plugin-graphql@1624

@executor-js/plugin-keychain

npm i https://pkg.pr.new/@executor-js/plugin-keychain@1624

@executor-js/plugin-mcp

npm i https://pkg.pr.new/@executor-js/plugin-mcp@1624

@executor-js/plugin-onepassword

npm i https://pkg.pr.new/@executor-js/plugin-onepassword@1624

@executor-js/plugin-openapi

npm i https://pkg.pr.new/@executor-js/plugin-openapi@1624

executor

npm i https://pkg.pr.new/executor@1624

commit: 16ea284

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
executor-marketing 16ea284 Commit Preview URL

Branch Preview URL
Aug 17 2026, 05:22 PM

@RhysSullivan
RhysSullivan marked this pull request as ready for review August 17, 2026 17:37
@RhysSullivan
RhysSullivan merged commit a8d3d3c into main Aug 17, 2026
20 of 21 checks passed
omega-alpha-matt Bot pushed a commit to airbooksio/executor that referenced this pull request Aug 18, 2026
)

* test: repro sign-out answering with a raw Unauthorized page

* fix: sign out browsers whose session has already ended

Sign-out was declared on the session-authenticated API group, so a browser
whose sealed session no longer authenticated at click time got a 401 from
SessionAuth instead of being signed out. The console posts sign-out as a
top-level form navigation, so that error body was rendered as the page:
a screenful of {"_tag":"Unauthorized"}.

Move the endpoint to the public group and read the sealed session off the
request cookie. Nothing here needs authorizing — the request can only end
the session whose cookie it presents — and the handler already fell back to
"/" when the cookie would not unseal.

Cookies are dropped only when the request actually presented one, so the
now-public endpoint cannot be used cross-site to sign a user out.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant