Skip to content

fix(security): require auth on GET /api/v1/reauth and stop leaking SAT in body - #293

Open
birme wants to merge 3 commits into
mainfrom
264-reauth-endpoint-auth
Open

fix(security): require auth on GET /api/v1/reauth and stop leaking SAT in body#293
birme wants to merge 3 commits into
mainfrom
264-reauth-endpoint-auth

Conversation

@birme

@birme birme commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add requireReAuth guard to GET /api/v1/reauth (mirrors requireWhipAuth): Bearer header with constant-time timingSafeEqual, 401 + WWW-Authenticate: Bearer realm="reauth". Auth is disabled when no key is configured so existing installs keep working.
  • Configurable via REAUTH_AUTH_KEY, falling back to WHIP_AUTH_KEY.
  • Defense in depth: stop returning the raw OSC service access token in the JSON response body ({ ok: true }); the httpOnly cookie remains the sole delivery path.
  • Warn at startup when /reauth is effectively unauthenticated (incl. whitespace-only key), so auth-off-by-default is never silent.
  • Adds test coverage for 401 paths (missing/empty/malformed Bearer) and the no-token-in-body behaviour.

Test plan

  • Tests pass (npm test)
  • TypeScript compiles (npm run typecheck)
  • Lint clean (npm run lint)
  • GET /api/v1/reauth with no/invalid Bearer returns 401 when REAUTH_AUTH_KEY/WHIP_AUTH_KEY is set
  • Response body no longer contains the token value; sat cookie is still set
  • Startup warning logged when a token is configured but no effective reauth key is set

Closes #264

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

The reauth endpoint was registered with a schema only - no preHandler,
no onRequest, no auth - so any unauthenticated caller could mint a valid
OSC service access token.

- Add requireReAuth, mirroring requireWhipAuth in api_whip.ts: Bearer
  header, constant-time timingSafeEqual comparison, 401 +
  WWW-Authenticate: Bearer realm="reauth", and auth disabled when no
  key is configured (existing installations keep working).
- Configure via REAUTH_AUTH_KEY, falling back to WHIP_AUTH_KEY.
- Defense in depth: stop returning the token in the JSON response body;
  the httpOnly cookie remains the delivery path.

Closes #264
QA review of #283: auth-off-by-default is the right call for backwards
compatibility, but it must not be silent. An install with
OSC_ACCESS_TOKEN set and no effective key still hands out a service
access token with no signal at all. A whitespace-only
REAUTH_AUTH_KEY is worse: it looks configured but is falsy after trim,
so auth is off while the operator believes it is on - the warning
distinguishes that case as a configuration error.

Also adds 401 coverage for empty Bearer, malformed header without the
Bearer prefix, and a token that is a proper prefix of the key.
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.

Security: /reauth endpoint returns raw OSC service access token in JSON response body

2 participants