Skip to content

[P0] Auth: resource exhaustion, state corruption, MCP entitlement gaps, and CI-skipped live suite #5379

Description

@koala73

Summary

Adversarial test sweep of the auth module found several confirmed security gaps where code behavior is currently correct but untested, and regressions would not be caught.

Census

  • Auth .mts files: 53 tests pass, 0 skip/fail
  • server/__tests__/gateway-user-key-apiaccess.test.ts: 10 pass, 0 skip/fail
  • API core (_api-key.js, _session.js, _user-api-key.js): 122 pass, 0 skip/fail
  • MCP/OAuth surfaces: 144 pass, 1 suite skipped (LIVE_API_CACHE_TESTS gate)

Confirmed gaps

High

  1. Resource exhaustion / DoSserver/auth-session.ts:81-98
    • Clerk plan fallback has no AbortSignal/timeout.
    • Temporary test with a valid no-plan JWT + never-settling Clerk fetch remained pending past 250ms.
    • An authenticated user with a standard no-plan session can pin gateway invocations when Clerk stalls.
  2. State corruption / EoPserver/_shared/user-api-key.ts:61-73
    • Cache/Convex result is cast without runtime shape validation.
    • A mocked validator returning truthy {} produced HTTP 200 instead of expected 401.
  3. Malformed-key amplificationserver/_shared/user-api-key.ts:34-46
    • Accepts any wm_ prefix; wm_x reached SHA-256/cache/backend although the real contract is wm_ + 40 hex.
  4. MCP entitlement predicates individually unguardedapi/mcp/auth.ts:315-319
    • Enforces tier>=1, mcpAccess===true, validUntil>=now.
    • Tests use one fixture violating all three; removing any single predicate leaves 144/144 green.
  5. Live auth/cache suite never executes in CItests/live-api-cache-auth-regression.test.mjs:77
    • Whole describe skipped unless LIVE_API_CACHE_TESTS=1; CI does not set it.
    • Mutation proof: unconditional throw at top of skipped describe still exited 0.
    • Authenticated MCP case at line 260 additionally requires WM_LIVE_TEST_KEY.

Medium

  1. Empty cached userId accepted — api/_user-api-key.js:215-218
  2. User-key request coalescing removal unguarded — api/_user-api-key.js:118-129,203-210 (DoS amplification)
  3. Convex AbortSignal timeout in user-key path not asserted — api/_user-api-key.js:174-190
  4. MCP authenticated per-minute limiter not exercised — api/mcp/auth.ts:370-400
  5. MCP anonymous discovery limiter not exercised — api/mcp/auth.ts:410-417
  6. Meta-test gap: secret-compare regex misses identifiers like probeSecret !== expectedSecrettests/no-non-timing-safe-secret-compare.test.mts:29-32,70-73

Design risk

  • server/__tests__/gateway-user-key-apiaccess.test.ts:210-218 deliberately enforces entitlement-null fail-open; a lapsed user who can induce or await that failure regains paid access.

Suggested fix

  • Add timeouts/AbortSignal to external auth lookups.
  • Validate user-api-key cache/Convex result shape before trusting it.
  • Enforce the wm_[0-9a-f]{40} contract before hashing/backend calls.
  • Split MCP entitlement fixtures so each predicate is individually tested.
  • Decide whether the entitlement-null fail-open posture is acceptable and test/document the choice.
  • Either provide CI secrets for the live auth/cache suite or replace it with recorded/mocked regression tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Critical, blocks release or core functionalityarea: APIBackend API, sidecar, keyssecuritySecurity-related

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions