password reset allows new password to be the same as the old password bypassing expected security controls
HackerOne report #1753748 by jlneel
on 2022-10-28:
Report
Summary
The password reset functionality allows a user to choose a new password that is the same as the old password. This is inappropriate validation of user inputs on the form. To handle this correctly the password reset functionality should hash the new password and confirm the hash is not the same as what is in database. if the new hash is the same as the old it should be rejected telling the user they need to choose a new password.
There are a few particularly concerning places for this
- When an account is initially setup by an admin they may use a weaker or standard password for when they hand out accounts. With users being able to go through set the same password this could led to users having weak passwords
- in Issue #371916 a gitlab support engineer provides guidance that the only way to force a password reset is to set the expiration time to a time in the past. but doing this would not require the user to set a new password as expected since they could just enter the form with their old password.
This vulnerability effectively makes it impossible for admins to require users to reset their password. This is a bypass of security controls in the application. There are many reasons this may need to be done.
Steps to reproduce
- login to the gitlab server as root
- navigate to the Users section in the admin area
- click create new user and fill out the form our user for this example will have the username
test
- edit the user by going to /admin/users/test/edit and set a new password for the user as admin. in this case we will say the password is
test1234
- login as
test
and you will be dropped into the force password reset captive portal. type intest1234
for the current password, new password, and confirm new password. - you will now be redirected to the login screen where you can login and get full access with the original
test1234
password that was set by the admin.
Additionally looking at the issue 371916 referenced above this can go one step further.
7. An admin wants to require that the test
user resets his password because it was compromised for one reason or another. The admin comes across the guidance from a gitlab support engineer and issues the following commands at the gitlab-rails console.
gitlab-rails console
--------------------------------------------------------------------------------
Ruby: ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
GitLab: 15.5.1-ee (7344dd2631a) EE
GitLab Shell: 14.12.0
PostgreSQL: 13.6
------------------------------------------------------------[ booted in 17.84s ]
Loading production environment (Rails 6.1.6.1)
irb(main):001:0> user = User.find_by_username('test')
=> #<User id:5 [@]test>
irb(main):002:0> user.password_expires_at = Date.today - 1
=> Thu, 27 Oct 2022
irb(main):003:0> user.save!
=> true
- The user
test
now logs in and gets dropped back into the captive portal to force a password reset. However thetest
user again enterstest1234
for the current password, new password, and confirm new password. - The
test
user is still able to login with thetest1234
password even after the admin believes the user has had to pick a new password twice.
Impact
This would affect all self hosted gitlab instances that leverage the built in authentication mechanisms. The primary impact would be a user being able to keep a password that is insecure for one reason or another.
With the addition of the feature suggested in #371916 this could potentially become a much bigger issue in the future if this functionality is made available to the admin in the UI.
Examples
see steps to reproduce
What is the current bug behavior?
A user is able to change their password so that the old password is the same as the new password
What is the expected correct behavior?
The forms for password reset should error if the new password is the same as the current and prompt the user for a new password.
Relevant logs and/or screenshots
N/A
Output of checks
N/A
Results of GitLab environment info
gitlab-rake gitlab:env:info
System information
System: Debian 11
Proxy: no
Current User: git
Using RVM: no
Ruby Version: 2.7.5p203
Gem Version: 3.1.6
Bundler Version:2.3.15
Rake Version: 13.0.6
Redis Version: 6.2.7
Sidekiq Version:6.4.2
Go Version: unknown
GitLab information
Version: 15.5.1-ee
Revision: 7344dd26
Directory: /opt/gitlab/embedded/service/gitlab-rails
DB Adapter: PostgreSQL
DB Version: 13.6
URL: http://gitlab..
HTTP Clone URL: http://gitlab../some-group/some-project.git
SSH Clone URL: git@gitlab.*.:some-group/some-project.git
Elasticsearch: no
Geo: no
Using LDAP: no
Using Omniauth: yes
Omniauth Providers:
GitLab Shell
Version: 14.12.0
Repository storage paths:
- default: /var/opt/gitlab/git-data/repositories
GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell
Impact
An attacker that has gained access to an account and knows the password could use this vulnerability to maintain persistence on a system that requires regular resets of user passwords. Say an attacker knows that he has the password and the password is required to be changed every 90 days. The attacker could use this to keep the password the same by always getting to this prompt before the legitimate owner of the account. With this the user would never realize they need to change the password.
How To Reproduce
Please add reproducibility information to this section: