Skip to content

Harden + test the Worker auth/identity gates #232

Description

@cameronapak

Part of #151

Question

Audit finding 4 (findings doc, from #159): the auth-boundary logic is untested and partly unhardened. One pass, four items:

  1. Extract + test the pure gatesresolveUserId (worker/index.ts:118, the DO tenant-isolation key: a regression here cross-wires two users' outlines), isAdminSession (:441), isPlausibleEmail (:436), and the invite-code predicate (worker/auth.ts:60-78) have zero test references and e2e can't reach them (the mock intercepts /api/auth). Extract to a pure module (the outline-ops.ts pattern, e.g. worker/identity.ts) and add a .test.ts: routing key equals user.id never email; empty/whitespace INVITE_CODES denies all; unknown/empty code denied; admin allowlist case-insensitive and fail-closed when unset.
  2. Assert BETTER_AUTH_SECRET — it is optional-typed and passed unguarded (worker/auth.ts:24,38); the "Better Auth fails closed in prod" comment is unverified library behavior. Add an explicit non-empty assertion at createAuth.
  3. Pin admin identity to user.id instead of an (unverified) email — closes the register-the-admin-email-first path permanently, even though the precondition is already false in prod.
  4. SSRF nitisPrivateIpv4 (worker/unfurl-core.ts:29) misses IPv4-mapped IPv6 ([::ffff:127.0.0.1]). Integer/hex forms are NOT a gap (WHATWG URL canonicalizes them); Cloudflare's platform block covers this anyway. One-line belt-and-suspenders while in the area.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions