Skip to content

auth hardening: generateOAuthState requires WebCrypto; OAuth callback rejects unparseable state #1562

Description

@cliffhall

Summary

Two small OAuth hardening fixes:

  1. generateOAuthState() (core/auth/utils.ts) throws when crypto.getRandomValues is unavailable instead of silently falling back to Math.random().
  2. The web OAuth callback handler (App.tsx) parses the returned state param and rejects anything that doesn't match the expected {mode}:{authId} shape, surfacing a clear error instead of proceeding.

Why

Math.random() is not a CSRF-grade entropy source — better to fail loudly on exotic runtimes than mint guessable state. And an unparseable state on the callback is a forgery indicator; rejecting it defeats simple CSRF attempts against the callback route.

Reference implementation (PR #1510)

Re-implement informed by these changes at 33fac3f:

  • core/auth/utils.tsgenerateOAuthState() throws without WebCrypto (+10/−13)
  • clients/web/src/App.tsx — OAuth callback state validation (small part of a larger diff; only the callback-handler hunks are in scope here)

Depends on

Nothing — Wave 1 foundation, parallel-safe.

Notes

  • In tests that exercise the throw path, suppress expected error output from the console per AGENTS.md.
  • Coverage gate ≥90 on all four dimensions for touched files.

Part of the PR #1510 decomposition (see tracking issue).

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions