Skip to content

fix: exempt PKCE recovery sessions from require-current-password check#2497

Closed
oelmgren wants to merge 1 commit intosupabase:masterfrom
oelmgren:fix/pkce-recovery-password-exemption
Closed

fix: exempt PKCE recovery sessions from require-current-password check#2497
oelmgren wants to merge 1 commit intosupabase:masterfrom
oelmgren:fix/pkce-recovery-password-exemption

Conversation

@oelmgren
Copy link
Copy Markdown
Contributor

Bug

UpdatePasswordRequireCurrentPassword in user.go only exempts sessions with otp or magiclink AMR claims from the current-password requirement. The PKCE recovery flow (the default path for the JS client) issues sessions with the recovery AMR claim:

  • recover.go:60 creates the flow state with models.Recovery.String() ("recovery")
  • token.go:256 parses it via ParseAuthenticationMethod(flowState.AuthenticationMethod)
  • token.go:265 issues the refresh token with models.Recovery
    The resulting JWT has "amr": [{"method": "recovery", ...}], which doesn't match "otp" or "magiclink". If the setting is enabled, updateUser({ password }) rejects the request with "Current password required" even though the user just came from a password reset email.

Fix

Add "recovery" to the AMR exemption check in user.go:176.

Test

Added a test case for models.Recovery AMR confirming current password is not required in PKCE recovery flow.

@oelmgren oelmgren requested a review from a team as a code owner April 22, 2026 16:52
Comment thread internal/api/user_test.go
desc: "Current password required for any other claim",
newPassword: "newpassword456",
recoveryType: models.EmailChange,
expected: expected{code: http.StatusBadRequest, isAuthenticated: true},
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oelmgren this isAuthenticated: true is incorrect, it works in the current tests because the step before had changed the password to newpassword456. The change password correctly fails, but the isAuthenticated check passes as true because the "newPassword" is the same as what is currently set in the database (bad test behaviour on my part, having side effects).

Suggested change
expected: expected{code: http.StatusBadRequest, isAuthenticated: false},

cstockton added a commit that referenced this pull request Apr 23, 2026
#2502)

This change fixes a unit test and uses gofmt on top of pr #2497.

---------

Co-authored-by: Ollie Elmgren <ollie@listenlabs.ai>
Co-authored-by: Chris Stockton <chris.stockton@supabase.io>
@cstockton
Copy link
Copy Markdown
Contributor

@oelmgren Thanks for the patch, I'm closing this pr as I've merged #2502 which cherry picks this pr and makes a couple minor changes.

@cstockton cstockton closed this Apr 23, 2026
@oelmgren
Copy link
Copy Markdown
Contributor Author

@oelmgren Thanks for the patch, I'm closing this pr as I've merged #2502 which cherry picks this pr and makes a couple minor changes.

Love it. Thx for the quick turnaround!

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.

3 participants