Problem/Motivation
The PasswordConstraint password_policy_character_constraint requires unique characters of each type. That is, if for example the module is configured to require passwords to include two numbers, a password which includes two incidences of the same number will fail validation. This runs counter to common user experience and actually decreases password security; if a malevolent user knows that a password contains any one character, they know that that character is not repeated anywhere in the password, making the password easier to crack.
Steps to reproduce
Enable this module, set a constraint requiring that passwords include two numbers, log in as a user to which this constraint applies and try to set the a new password that includes two of the same numbers. (This problem is not limited to numbers; the same is true for letters, upper case letters, lower case letters and special characters.)
Proposed resolution
Alter the logic in PasswordCharacter::validate() to add the number of incidences of each character instead of increasing counters by one.
For example, change:
if (is_numeric($char)) {
$count_numeric++;
}
to:
if (is_numeric($char)) {
$count_numeric = $count_numeric + $val; // Here, $val is the the number of incidences of the $char in the password.
}
Remaining tasks
Community discussion is appropriate as to whether we should adapt the module's admin language (see related issue Instructions unclear for constraint of Uppercase and Lowercase Characters) to align with the module's requirement that characters used be unique or should we remove that requirement.
Patch forthcoming.
Issue fork password_policy-3236423
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
cobadger commentedPatch attached.
Comment #4
cobadger commentedUpdated patch with correction to unit test.
Comment #6
hmendes commentedHello,
When a first used this functionality I was also confused about this, when I read the description I thought this constraint was to count the amount of characters in the password for each type ( not about unique characters ), and that's why we had the issue #2894929: Instructions unclear for constraint of Uppercase and Lowercase Characters to change these descriptions to make it clearer.
Although I think this could be done, I also think that the initial functionality ( with unique characters ) might be a good idea... I think we could we add an option, a checkbox, to choose between counting unique characters or count every character, what do you think?
Comment #7
cobadger commented(Updated patch with corrected unit testing attached.)
@hmendes thank you for your thoughts on whether or not we want to provide a unique character password constraint. I believe that requiring unique characters decreases password security: Of the top 10,000 most commonly used passwords, only about 36% contain only unique characters (see attached "most-common-10000-passwords-unique-characters.ods"), so enforcing a unique character constraint would make it about 64% easier for common password attacks to work - a significant decrease in password security.
Comment #9
cobadger commentedComment #10
cobadger commentedI sincerely apologize for bombing this ticket with updated versions of the patch. The attached patch's tests should all pass this time.
Comment #11
marcos_lima commentedHi @COBadger! Thanks for the patch! I tested it and did a code review. I installed the module, tested the password change before and reproduced the issue, then tested again after applying the patch and the expected behavior (counting two or more incidences of the same character) was working fine. The code logic and modifications seem good to me! I would just like to get some more info on the test changes, because I think it is redundant with the previous data. If you meant for it to test the new behavior, I think the data should be:
To assert if it is really counting the two “s” as two letters. The way it is, with ‘passw’, it would pass in the previous behavior and in the proposed one, thus becoming redundant.
As seen by the last provided data in the test, I think it was expected during its implementation that this functionality enforced unique characters in its constraints.
I agree with @COBadger thought that it is counterintuitive and runs against common user experience. From what I understood reading the IS and the discussion, this constraint should either:
Right?
I prefer the first approach, which is the one proposed, and agree with @COBadger arguments. Then we could add the unique characters constraint as a feature request if the community thinks it is needed.
I’m moving it back to Needs Work and assigning myself to make that test change. Apologies if I misunderstood something and thank you for the patch. I hope my thoughts were useful for the discussion.
Comment #12
marcos_lima commentedHi! Attached is the patch with the change in the test data and the interdiff from the previous patch.
Comment #13
huriellopes commentedSteps performed:
(1) Module installed
(2) Reproduction of the problem.
(3) Patch applied.
(4) Code review on changes.
(5) Retested with patch, issue resolved.
Comment #16
kristen polAssigning to myself as I'm reviewing/merging ready RTBC fixes/updates over the next few days.
Comment #17
kristen polThis should be against 4.0.x as 8.x branches are no longer supported, so changing version.
Comment #18
kristen polThanks everyone for the work on this issue. Moving back to needs work based on the following:
I've tested the original behavior and read the summary and comments above.
1. Regarding repeating characters, I found this:
https://www.quora.com/How-does-restricting-password-length-or-repeating-...
I ready some other posts that talk about this as well. So, rather than add a "unique" checkbox per #6, I think we can move forward with this approach.
But this claims to be a list of NIST guidelines:
https://blog.netwrix.com/2022/11/14/nist-password-guidelines
which has:
There is already a consecutive character constraint that can be used though I don't see a sequential one. A separate feature request issue can be created to add sequential character constraint.
2. The MR does not match the most recent patch. I'm okay with an MR or patch, so whoever updates can do either.
3. Nitpick: The logic could be slightly simpler, e.g.
could be:
4. The documentation/messages should be updated to reflect these changes:
#2894929: Instructions unclear for constraint of Uppercase and Lowercase Characters
Comment #19
cobadger commentedNot sure why it's not automatically being added to this page, but I created a new MR against 4.0.x:
https://git.drupalcode.org/project/password_policy/-/merge_requests/72
Comment #20
kristen polAssigning to myself for review.
Comment #22
kristen polThanks everyone. I reviewed the code and tested MR 72 and it works as expected. This has been merged and will be in the next release.
That said, there still might be missing tests. Don't we want to test things like the following? If so, we can have a followup issue with more tests.
1. We set min numbers to 3 and we set password to 3 numbers that are the same.
2. We set min numbers to 3 and we set password to 3 numbers that are the different.
3. We set min numbers to 3 and we set password to 2 numbers that are the same (or different).
4. We set min numbers to 3 and we set password to 4 numbers that are the same (or different).
Comment #24
kristen polThis is part of the new 4.0.1 release.