[Feature:System] Configurable password requirements#12455
Conversation
IDzyre
left a comment
There was a problem hiding this comment.
Looks like a good start, and pretty close for a full security review.
I personally think that we shouldn't allow the password requirements to "not be defined", and require them to be in the config.
The goal of this is to consolidate the code that we have to change if the password requirements were to be updated, and this adds multiple extra places where we have to double check to make sure they are the same.
Also, could you update the Cypress login tests to reflect the different password requirements shown?
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #12455 +/- ##
============================================
+ Coverage 21.48% 21.50% +0.01%
- Complexity 9842 9861 +19
============================================
Files 268 268
Lines 36851 36863 +12
Branches 495 495
============================================
+ Hits 7919 7928 +9
- Misses 28441 28444 +3
Partials 491 491
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
…down(), and add Cypress password validation tests
45dce5c to
c607dc5
Compare
|
@IDzyre I've addressed your feedback. Can you take another look? |
IDzyre
left a comment
There was a problem hiding this comment.
Looks good on the requirements, and functionality code, I need to do a review on the visual side, but a small question.
99593a9 to
ee66e07
Compare
|
@IDzyre i have implemented all your feedback, can you look into it |
|
I tested the functionality of this PR, by first attempting to create a new account, and then attempting to change the password for an already existing account. In both instances, the password requirement behavior worked as expected, with only matching passwords that fulfilled the minimum standard being accepted. However, when the password validation failed, somewhat annoying behavior occurred. In the account creation page, all fields were cleared, erasing the email, user id, and name. In the profile page, I was automatically redirected to the homepage, even when the password didn't update. This seems to be because the logic for password validation is fully server-side, so an invalid post request will redirect to a given page, possibly clearing all fields. If this logic could be added to the client-side, it would prevent this from being an issue. Additionally, I have a minor concern about the isValidPassword in site/app/libraries/Utils.php. The function repeatedly uses preg_match to check whether a password fulfills a given requirement. As far as I can tell, preg_match is not a constant-time function, meaning it can leak secret data (in this case a password) based on the time it takes to evaluate the function. This does not appear to be a critical security issue, but I think it would be wise to fix now. |
@Eli-J-Schwartz I've noticed the same field-clearing issue happens when email or user ID validation fails too, all fields get cleared on the redirect. Should I create a separate issue to add client-side validation for those fields, or would you prefer I include it in this PR? |
|
Since the purpose of this PR is for the passwords, if you fix them in this PR, I suggest that you create an issue, outlining what you did to fix it for passwords in this PR. (You can solve that issue in another PR if you wish as well) |
aa8283d to
9867f81
Compare
|
@IDzyre I’ve made the requested changes. Could you please review them |
|
I will review it when I have time, I am currently a student in University, and it is an exam week, so I haven't done much reviewing. Sorry for the wait. |
NicholasCiuica
left a comment
There was a problem hiding this comment.
I've tested the changes in this PR, and found everything to be working as expected. However, I've found some issues with the tests for this feature, and I have also left some feedback on opportunities for code reuse and bettering the password-matching frontend feedback.
Additionally, I don't see any tests for changing a current account's password. Given the new password requirements, I feel it will be valuable to test changing passwords in a similar way to how this PR tests account creation.
| cy.get('[data-testid="sign-up-button"]').click(); | ||
| cy.get('[data-testid="popup-message"]').should('contain.text', 'Password does not meet the requirements'); | ||
| // Password missing uppercase | ||
| inputData(undefined, undefined, 'nouppercase#123', 'nouppercase#123'); |
There was a problem hiding this comment.
I am not sure how to edit configurations within a Cypress test, but I believe that would solve this issue; set "require_uppercase", "require_lowercase", "require_numbers", and "require_special_chars" to true in /usr/local/submitty/config/submitty.json at the start of the test
addresses the following issues: now clears text fields after failing to sign in (in case page isn't reloaded after sign in fails); randomizes username and email that is used to sign in so the current contents of the database (likely) wont affect the current test run; commented out a number of password requirement tests that currently don't work because we are not yet capable of changing configs within cypress tests
I made the ChangePasswordForm and the CreateNewAccount form use the same frontend password validation. I ended up not reusing the checkPasswordsMatch function within the checkSubmittedPassword function, in the case that we want them to do different things later down the line (checkPasswordsMatched is currently called whenever you unfocus from the Confirm Password field of the Create Account form)
|
I made some changes to fix the failing password tests. Importantly, I commented out a number of the password complexity Cypress tests because the password complexity requirements are now disabled by default, so a GitHub action will likely need to be made which enables these configs before the test runs and disables them afterward. I also consolidated the frontend password validation logic for the Change Password/Create Account forms into a single function within authentication.js. A note to people newly looking at this PR: you have to enable DatabaseAuthentication and create_user_account to test the features added, https://submitty.org/sysadmin/configuration/self_account_creation |
### Why is this Change Important & Necessary? Relates to [#12455](#12455) ### What is the New Behavior? The self_create_account Cypress test now randomizes the user id and email used when trying to create a new account during testing, so that the database contents of the testing VM don't affect this test. Originally, this test would break whenever it was run more than once locally or in CI, because the new user that the first attempt at the test made affects how the next attempts run. ### What steps should a reviewer take to reproduce or test the bug or new feature? enable DatabaseAuthentication and create_user_account to test the features added, https://submitty.org/sysadmin/configuration/self_account_creation run the self_create_account Cypress test locally multiple times. You will see the "User ID or email already attached to an account" display where it shouldn't be. <img width="743" height="511" alt="Screenshot 2026-06-08 170523" src="https://github.com/user-attachments/assets/d58f4d67-cc9e-477b-9d22-4f23b6695b6f" /> ### Other information This PR is a portion of the changes I have committed to [#12455](#12455), but this bugfix is important for working on other database-related PRs.
|
It passed locally when I added the feature, not sure what caused that. |
changes configs in CI to enable password complexity requirements for the duration of the password tests. These tests will fail locally because password complexity is disabled by default
new spec to test changing passwords. i need to make a cleanup step after i disable password complexity requirements to revert the password set in this spec.
opted to keep change password spec self-contained, so I make a new account just for that test instead of changing the password of any other account made during setup or testing.
|
I have added steps in the CI to the enable password complexity requirements in the configs for the duration of this PR's Cypress tests, and have re-enabled my password complexity tests within the self_account_creation spec. I also made a new change_password spec that tests the ability for a user to change their password given the password complexity configs introduced in this PR. I believe this PR is ready to be reviewed. Please see original post and my above comments for testing instructions. |
dagemcn
left a comment
There was a problem hiding this comment.
I did a functionality test on this PR, I tested the rendering of password requirements, the enforcements of password requirements and that changing the password still actually updated the password. All worked as intended. The cypress tests for database authentication are a good addition as previously this functionality was untested to my knowledge. Looks good to me, failing CIs seem to be the ones we already know are flaky or failing.


Why is this Change Important & Necessary?
Closes #12341
Password requirements are currently hardcoded (12+ chars, uppercase, lowercase, number, special character). Institutions cannot customize these rules to match their own password policies. Additionally, the Change Password modal has no validation and does not display any requirements to the user.
What is the New Behavior?
password_requirementsinsubmitty.jsonpassword_requirementsto existing installationsChange Password modal now shows requirements:
Sign Up page reflecting custom config (min_length changed to 8):
What steps should a reviewer take to reproduce or test the bug or new feature?
/authentication/create_account— verify requirements are still displayed correctlypassword_requirementsin/usr/local/submitty/config/submitty.json(e.g., setmin_lengthto 8,require_special_charsto false) — verify both Sign Up and Change Password reflect the updated configAutomated Testing & Documentation
Unit tests added for
isValidPassword()with custom requirements and max length validation inUtilsTester.php.Other information
Includes a system migration (
20260220120000_add_password_requirements.py) to add defaultpassword_requirementsconfig to existing installations.