fix(connect): hard-fail OAuth callback when Redis unavailable #478
fix(connect): hard-fail OAuth callback when Redis unavailable #478hariom888 wants to merge 9 commits into
Conversation
The CSRF nonce check in /connect/github/callback was guarded by if (app.redis && ...), meaning a Redis outage silently bypassed all CSRF verification. An attacker could craft a base64 state for any userId, submit a stolen OAuth code to the callback, and have a github_follow token stored under an arbitrary user's account. Changes: - Replace the conditional CSRF guard with an explicit hard-fail: if !app.redis || app.redis.status !== 'ready', return 503 immediately. The callback never reaches token exchange or DB writes without a verified nonce. - Remove all �pp.redis ? ... : null ternaries from the callback path — every Redis access is now unconditional, matching the initiator's strictness. - Nonce deletion ( edis.del) is now unconditional after a successful verification, preventing replay attacks. Tests added (connect.test.ts): - Redis unavailable (status !== 'ready') → 503, no upsert - Redis is null/falsy → 503, no upsert - Crafted state with unknown nonce → invalid_state redirect, no upsert - Nonce present but userId mismatch → invalid_state redirect, no upsert - Valid round-trip → connected=github redirect, nonce consumed - Nonce replay → second request rejected after first consumes the nonce - Missing code/state params → missing_params redirect - Malformed base64 state → connect_failed redirect
|
@hariom888 is attempting to deploy a commit to the Prashantkumar Khatri's projects Team on Vercel. A member of the Team first needs to authorize it. |
CI — Checks FailedBackend — FAIL
Mobile — SKIP
Web — FAIL
Last updated: |
Typecheck failure is pre-existing on
|
Harxhit
left a comment
There was a problem hiding this comment.
Fix lint error in connect.ts file.
Signed-off-by: hariom888 <hariom880088@gmail.com>
|
All remaining CI failures are pre-existing on Lint: Test: Typecheck: All 14 errors are in connect.test.ts: ✅ 8/8 tests pass. |
Summary
Fixes #438.
/connect/github/callbackguarded its CSRF nonce check behindif (app.redis && ...). A Redis outage silently removed the entire guard while still allowing the OAuth exchange to proceed — withuserIdtaken directly from the attacker-controlled base64stateparameter. An attacker who could predict or observe the state format could store a token under any arbitrary user's account.Root cause
Fix
Hard-fail immediately if Redis is not ready. The callback cannot safely proceed without nonce verification.
This mirrors the strictness of the initiator (
GET /github), which already unconditionally callsapp.redis.set— making Redis a hard dependency for both ends of the flow.Test coverage
app.redisis nullinvalid_stateinvalid_stateconnected=github, nonce consumedinvalid_statemissing_paramsconnect_failedFiles changed
apps/backend/src/routes/connect.tsapps/backend/src/__tests__/connect.test.ts