Skip to content

fix(oauth): prevent authorization-code replay race at /oauth/token#2612

Open
reactima wants to merge 1 commit into
supabase:masterfrom
reactima:fix/replay-race-2026-07-02
Open

fix(oauth): prevent authorization-code replay race at /oauth/token#2612
reactima wants to merge 1 commit into
supabase:masterfrom
reactima:fix/replay-race-2026-07-02

Conversation

@reactima

@reactima reactima commented Jul 2, 2026

Copy link
Copy Markdown

fix(oauth): prevent authorization-code replay race at /oauth/token

What

Fixes an authorization-code replay race (TOCTOU) in the authorization_code grant at POST /oauth/token.

Why

handleAuthorizationCodeGrant read the code (FindOAuthServerAuthorizationByCode) and validated expiry/client/redirect_uri/PKCE with no transaction or row lock, opening a transaction only later to issue tokens and Destroy the code. Two requests with the same code can both clear validation before either commits; tx.Destroy's DELETE matching 0 rows still commits under READ COMMITTED — so both mint a full token set for one single-use code, violating RFC 6749 §4.1.2 / PKCE.

The authorize/consent path was hardened in #2512; token-exchange never got the equivalent locked read-modify-write.

Change

  • Reuse FindOAuthServerAuthorizationByIDForUpdate (fix(oauth-server): serialize concurrent authorize/consent with row-level lock #2512's FOR UPDATE SKIP LOCKED helper) to lock the row at the top of the issuing transaction. Concurrent redemptions serialize — the loser skips the locked row and gets invalid_grant. No new model code.
  • Propagate *apierrors.OAuthError out of the transaction so invalid_grant reaches the client instead of a 500.

Impact

No schema/API changes. Behavior differs only under concurrent redemption of the same code.

Testing

go build ./... and go vet pass. Reproduction: N concurrent exchanges of one fresh code behind a start barrier — before, ≥2 responses carried access_token; after, exactly one succeeds and the rest return 400 invalid_grant (success <= 1).

@reactima reactima requested a review from a team as a code owner July 2, 2026 16:18
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.

1 participant