Skip to content
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

XWIKI-21571: Change default value of the reset password token lifetime #3012

Merged
merged 7 commits into from Mar 27, 2024

Conversation

surli
Copy link
Member

@surli surli commented Mar 21, 2024

Jira URL

https://jira.xwiki.org/browse/XWIKI-21571

Changes

Description

Change the mechanism of the reset password token to not reset it at each verification code check, but only when the password is actually reset, or when its lifetime expired.
This PR also provides some refactoring: a mandatory document initializer has been brought for the ResetPasswordRequest xclass and the integration tests for reset password / ask forgotten username have been put in the security-authentication module since the logic is there. Also default value of the token lifetime is now 60 minutes.

Clarifications

Old behaviour of the reset password token was to revoke it immediately at first access, even if the password wasn't reset, or if a token lifetime configuration was provided (which wasn't by default) to use that duration to then revoke it. So basically the mechanism to revoke it was entirely based on access.

Now the mechanism is mainly based on its lifetime, defined by the configuration property which has been set to 1h by default: if the token is accessed after its lifetime duration, the token is revoked and an error is displayed to the user (which has been improved). If the token is accessed before its lifetime duration the token is kept until the password is reset: so if the user doesn't finish the process they can resume it later. Also if the user uses a wrong token (e.g. if they reuse an old token for some reason) the new token is not immediately revoked, as we consider it will be revoked after its lifetime duration. Now if no lifetime duration is provided (old default value of the property was 0) then we do revoke the token at first wrong access for security to avoid any bruteforce.

Screenshots & Video

image

Executed Tests

Run of mvn clean install -Pquality,integration-tests,docker on xwiki-platform-security-authentication

  • Check integration tests
  • Test manually the reset password

Expected merging strategy

  • Prefers squash: Yes
  • Backport on branches:
    • 15.10.x ⚠️ there's new modules on this PR, we need to be careful with the backport

Change the mechanism of the reset password token to not reset it at each
verification code check, but only when the password is actually reset,
and when its lifetime expired.
Also provide a mandatory document initializer for the
ResetPasswordRequest xclass.
@surli surli added the backport stable-15.10.x Used for automatic backport to 15.10.x branch. label Mar 21, 2024
Change a bit more the logic: if the token lifetime configuration is set
to 0 (which was the default) then we automatically remove the reset
password request xobject at first wrong attempt (bad verification code):
it will prevent any bruteforce attack. Then if there's a token lifetime
configuration set, we don't remove the xobject when a bad attempt is
performed: user might have used the wrong mail for example. But we do
remove the xobject when it's expired. And if it's expired, or if the
code was wrong, in both cases we immediately return an error.
Move ResetPasswordIT and ForgotUserNameIT from
administration-test-docker to a new module
security-authentication-test-docker since it's related to
security-authentication module now.
@surli surli marked this pull request as ready for review March 25, 2024 08:13
  * Ensure to properly set the user before update config in integration
    tests
}
} else if (userInformation.userExists && userInformation.userEmail == null) {
// In case the mail is not configured, we log a message to the admin.
this.logger.info("User [{}] asked to reset their password, but did not have any email configured.",
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this information be communicated to the user requesting for a password reset?

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that I haven't changed the behaviour here, it's just that the diff is not easy to read. So I don't want to change that now. AFAIR we decided to always display the minimum of information when trying to reset a password so it basically always say the same thing to prevent any kind of data leak.
We could decide to change that but IMO it deserves a dedicated ticket.

surli and others added 2 commits March 26, 2024 10:36
…urity-authentication/xwiki-platform-security-authentication-default/src/main/java/org/xwiki/security/authentication/internal/DefaultResetPasswordManager.java

Co-authored-by: Manuel Leduc <manuel.leduc@xwiki.com>
@surli surli merged commit b410dad into master Mar 27, 2024
1 check passed
@surli surli deleted the XWIKI-21571 branch March 27, 2024 13:18
github-actions bot pushed a commit that referenced this pull request Mar 27, 2024
#3012)

Change the mechanism of the reset password token to not reset it at each
verification code check, but only when the password is actually reset,
and when its lifetime expired.
Also provide a mandatory document initializer for the
ResetPasswordRequest xclass.

Change a bit more the logic: if the token lifetime configuration is set
to 0 (which was the default) then we automatically remove the reset
password request xobject at first wrong attempt (bad verification code):
it will prevent any bruteforce attack. Then if there's a token lifetime
configuration set, we don't remove the xobject when a bad attempt is
performed: user might have used the wrong mail for example. But we do
remove the xobject when it's expired. And if it's expired, or if the
code was wrong, in both cases we immediately return an error.

Move ResetPasswordIT and ForgotUserNameIT from
administration-test-docker to a new module
security-authentication-test-docker since it's related to
security-authentication module now.

---------

Co-authored-by: Manuel Leduc <manuel.leduc@xwiki.com>
(cherry picked from commit b410dad)
surli added a commit that referenced this pull request Mar 27, 2024
#3012)

Change the mechanism of the reset password token to not reset it at each
verification code check, but only when the password is actually reset,
and when its lifetime expired.
Also provide a mandatory document initializer for the
ResetPasswordRequest xclass.

Change a bit more the logic: if the token lifetime configuration is set
to 0 (which was the default) then we automatically remove the reset
password request xobject at first wrong attempt (bad verification code):
it will prevent any bruteforce attack. Then if there's a token lifetime
configuration set, we don't remove the xobject when a bad attempt is
performed: user might have used the wrong mail for example. But we do
remove the xobject when it's expired. And if it's expired, or if the
code was wrong, in both cases we immediately return an error.

Move ResetPasswordIT and ForgotUserNameIT from
administration-test-docker to a new module
security-authentication-test-docker since it's related to
security-authentication module now.

---------

Co-authored-by: Manuel Leduc <manuel.leduc@xwiki.com>
(cherry picked from commit b410dad)
surli added a commit that referenced this pull request Mar 27, 2024
#3012)

Change the mechanism of the reset password token to not reset it at each
verification code check, but only when the password is actually reset,
and when its lifetime expired.
Also provide a mandatory document initializer for the
ResetPasswordRequest xclass.

Change a bit more the logic: if the token lifetime configuration is set
to 0 (which was the default) then we automatically remove the reset
password request xobject at first wrong attempt (bad verification code):
it will prevent any bruteforce attack. Then if there's a token lifetime
configuration set, we don't remove the xobject when a bad attempt is
performed: user might have used the wrong mail for example. But we do
remove the xobject when it's expired. And if it's expired, or if the
code was wrong, in both cases we immediately return an error.

Move ResetPasswordIT and ForgotUserNameIT from
administration-test-docker to a new module
security-authentication-test-docker since it's related to
security-authentication module now.

---------

Co-authored-by: Manuel Leduc <manuel.leduc@xwiki.com>
(cherry picked from commit b410dad)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport stable-15.10.x Used for automatic backport to 15.10.x branch.
Projects
None yet
2 participants