Open emteknetnz opened 1 month ago
Couple of questions that I think I know the answer to but want to confirm:
Member
objects by default, right? For example both members with access to the CMS and those just registering as a website user (assuming a website allows registration)?IMO I think it's worth using the jump to 6 to meaningfully improve security, so I'm more in favour of a jump to PasswordStrength::STRENGTH_STRONG
as a default, as long as you can change it easily and we document it clearly in the upgrade guide. If it's a YML change to get back to (something close to) the old settings, even if it's not exactly the same, this seems like an easy decision for people to make, while still ensuring that new builds and those more security conscious sites get a safer experience out of the box.
It means we have to trust people upgrading will look at the docs - but I think that should be a given.
Overall, I'm in favour of going to STRENGTH_STRONG
as a default so long as it's easy to revert - but I don't feel super passionate about it either. Call it 75% in favour, 25% against :)
- When upgrading, you're not forced to enter a new valid password in order to log in, right? It's just when you next go to change your password, reset your password or create a new user that you'd be required to do so?
Correct - there is no retrospective validation of passwords. Password validation only happens when you're setting a new password.
- This would apply for all Member objects by default, right? For example both members with access to the CMS and those just registering as a website user (assuming a website allows registration)?
Yup, unless there's some custom logic changing how that works.
- This would be easy to override, via YML config?
Very easy, yes
- Can we emulate the old behaviour in some way easily, for those that want to opt out - without introducing jank like a custom validator or other annoying-thing-we-will-want-to-deprecate-later?
The old behaviour is retained in the RulesPasswordValidator
which you can set via YAML config or via PHP code.
- Finally, how do we display validation failures - it's not necessarily as easy as saying "just make sure you have uppercase, lowercase, numbers and symbols and at least X characters" anymore as it's not a set of YML values, rather it's a strength rating, right? I guess we could type a user-friendly description to each of the different default strengths...
The validation error message in ConfirmedPasswordField
for CMS 6 is "The password strength is too low. Please use a stronger password."
That's the same as the message from symfony's validation logic, which is what the EntropyPasswordValidator
uses.
There are a variety of messages in the RulesPasswordValidator
depending on what validation fails.
I agree that we should meaningfully increase security, though I think I'd still prefer STRENGTH_MEDIUM
as a default simply because requiring more than 16 chars for a basic style password feels like it goes past some sort of psychological barrier for me. We should probably avoid STRENGTH_WEAK
if for no other reason that it has the word WEAK
in there which makes justifying it hard.
Ideally we'd have a UX component in the password field that provides feedback to the user about password strength as you type, it could be as simple as a line of text below the input element that says "Password strength: weak".
This sounds like a good compromise to me. Increase security but without making it insanely difficult for the average user. I'm a 👍🏼 to using STRENGTH_MEDIUM
.
Thanks for the detailed feedback @GuySartorelli, all sounds great to me, and awesome that there's the RulesPasswordValidator
that you can fallback to. In that case, so long as we document that in the upgrade guide as a fallback option if you want to retain your previous rules, then that sorts out any issues with increasing the default requirement.
It's also worth thinking about our overall strategy around passwords here - one of the reasons for long / complex passwords is to avoid brute force attacks. That's not as relevant for Silverstripe because of the lockout system that only allows you a small number of tries within 15minutes before getting locked out - meaning that brute forcing is essentially impossible for passwords a lot shorter than 16 characters.
Brute force attacks can also be used if someone gets a dump of the database (though granted the attack strategy changes a little in that scenario), so any password strategy should always take them into account.
Yeah, that is certainly true and is a valid consideration (nice shout @GuySartorelli, thanks!), although there's a lot worse that attackers are likely to do with a full database dump from any site that isn't purely public information. I reckon MEDIUM
strikes a reasonable balance - and people can always choose to make it harder as well.
Thanks for the feedback, sounds like we should set it to MEDIUM, which is the default level in symfony/validator
I've made a proof of concept for the UX feedback, PRs linked in description
Here's a video of the POC https://www.youtube.com/watch?v=HAFfEhTzcBo
Overall what you've shown in the video looks neat. Won't make sense when a different validation callback is passed into ConfirmedPasswordField
or when a different password validator is applied to Member
.
In the use symfony/validator work the new EntropyPasswordValidator was made the default PasswordValidator for CMS 6, however this appears to be a bit too strong compared to CMS 5
We set the EntropyPasswordValidator to have a default strength on
PasswordStrength::STRENGH_STRONG
. This means you now require a password of at least 16 characters, and 19 characters if using a passphraseThe default password validation in CMS 5 is only 8 characters. This goes up to 10 if using cwp-core or similar configuration was used, and you also needed some uppercase / punctuation characters in there too
Given that STRENGTH_STRONG is such a departure from CMS 5, it seems like we should either (in order of smallest to biggest change)
@madmatt Do you have any views on this?
Comparison of what passes the password validators
CMS 5 - silverstripe/installer
CMS 5 - silverstripe/installer with cwp/cwp-core config https://github.com/silverstripe/cwp-core/blob/3/_config/security.yml#L9
CMS 6 - PasswordStrength::STRENGTH_VERY_WEAK;
Symfony throws an Exception :-) Minimum score is actually STRENGTH_WEAK
CMS 6 - PasswordStrength::STRENGTH_WEAK;
CMS 6 - PasswordStrength::STRENGTH_MEDIUM;
CMS 6 - PasswordStrength::STRENGTH_STRONG;
CMS 6 - PasswordStrength::STRENGTH_VERY_STRONG;
Didn't test
Acceptance criteria
Video of POC
https://www.youtube.com/watch?v=HAFfEhTzcBo
PRs