-
Notifications
You must be signed in to change notification settings - Fork 609
feat: check current password on change #2364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -18,6 +18,7 @@ import ( | |||||
| type UserUpdateParams struct { | ||||||
| Email string `json:"email"` | ||||||
| Password *string `json:"password"` | ||||||
| CurrentPassword *string `json:"current_password,omitempty"` | ||||||
| Nonce string `json:"nonce"` | ||||||
| Data map[string]interface{} `json:"data"` | ||||||
| AppData map[string]interface{} `json:"app_metadata,omitempty"` | ||||||
|
|
@@ -165,6 +166,31 @@ func (a *API) UserUpdate(w http.ResponseWriter, r *http.Request) error { | |||||
| isSamePassword := false | ||||||
|
|
||||||
| if user.HasPassword() { | ||||||
| // current password required when updating password | ||||||
| if config.Security.UpdatePasswordRequireCurrentPassword { | ||||||
| // user may be in a password reset flow, where they do not have a currentPassword | ||||||
| isRecoverySession := false | ||||||
| for _, claim := range session.AMRClaims { | ||||||
| // password recovery flows can be via otp or a magic link, check if the current session | ||||||
| // was created with one of those | ||||||
| if claim.GetAuthenticationMethod() == "otp" || claim.GetAuthenticationMethod() == "magiclink" { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 Severity: HIGH The AMR check to exempt recovery sessions is overly broad. Since 'otp' and 'magiclink' are used for standard passwordless sign-ins, any user authenticated via these methods can bypass the 'require current password' policy. This allow an attacker with access to a passwordless session to change the account password without knowing the existing one. 💡 Fix SuggestionSuggestion: Change the AMR check to specifically look for the 'recovery' authentication method instead of the overly broad 'otp' or 'magiclink' checks. The 'recovery' authentication method (models.Recovery) is the specific marker for password recovery flows, while 'otp' and 'magiclink' are used for standard passwordless sign-ins. This prevents users with regular OTP or MagicLink sessions from bypassing the current password requirement.
Suggested change
|
||||||
| isRecoverySession = true | ||||||
| break | ||||||
| } | ||||||
| } | ||||||
| if !isRecoverySession { | ||||||
| if params.CurrentPassword == nil || *params.CurrentPassword == "" { | ||||||
| return apierrors.NewBadRequestError(apierrors.ErrorCodeCurrentPasswordRequired, "Current password required when setting new password.") | ||||||
| } | ||||||
| isCurrentPasswordCorrect, _, err := user.Authenticate(ctx, db, *params.CurrentPassword, config.Security.DBEncryption.DecryptionKeys, false, "") | ||||||
| if err != nil { | ||||||
| return err | ||||||
| } | ||||||
| if !isCurrentPasswordCorrect { | ||||||
| return apierrors.NewBadRequestError(apierrors.ErrorCodeCurrentPasswordMismatch, "Current password required when setting new password.") | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
staaldraad marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| auth, _, err := user.Authenticate(ctx, db, password, config.Security.DBEncryption.DecryptionKeys, false, "") | ||||||
| if err != nil { | ||||||
| return err | ||||||
|
|
||||||
Uh oh!
There was an error while loading. Please reload this page.