I implemented a couple of password requirements and I’m not sure I put my code in the proper location (Version 9.2.1 - concrete/controllers/single_page/account/edit_profile.php - save function and concrete/authentication/concrete/controller.php - change_password function). I know there are always multiple ways to implement things. With that said, what is the best method for enforcing new password requirements? I implemented a check that ensures the password is at least 1 day old (24 hours) before allowing it to be changed again. Additionally, when the password is changed, I implemented another check requiring at least 8 of the characters of the password be changed. Any help would be greatly appreciated.
Have you checked out the built-in password requirements in the Dashboard? You might not need to override core files to achieve what you are looking for they can be found in Dashboard → System & Settings → Login & Registration → Password Requirements
If you do choose to override core files please be aware that whenever you upgrade the site anything you change in the concrete directory will be wiped out, you should override things in the application directory.
As per @Hutman’s second point, a danger with modifying core files is that the next time you update your site core version you will need to apply the changes all over again. Better to override them with files in /application or /packages.
There is a core change password event. Perhaps that is an easier way to enforce password format without need to override (I have never used this event, so am not writing from expertise - just something you could look into)
Having said that, if your interest in adding password requirements is enhanced security, consider instead a 2FA system such as:
Per both of your suggestions, I was able to figure out how to override the Concrete Core Password Validator Service Provider (\Concrete\Core\Validator\PasswordValidatorServiceProvider) in the application folder to solve the minimum password requirement age of 1 day. However, I’m still not sure how to handle the other requirement of changing at least 8 characters of the password.
Since the current password is stored with a one-way hash, I can’t compare the new password with the old password using the Password Validator Service Provider. The plaintext version of the current password is not available there. However, in the Edit Profile form (concrete/single_pages/account/edit_profile.php), the user enters their current password and the new password. When saved the controller save function (concrete/controllers/single_page/account/edit_profile.php) has access to both and I can compare them there. I know I can override that and add my code in the application folder. Is that the proper or only place to do it?
Saving the unhashed user password on the server would create more security risks than it could ever solve.
What do you mean by saving the unhashed user password on the server? From my understanding, I’m not doing anything more than what is already being done in the code. The following lines of code already exist:
$passwordCurrent = (string) $data[‘uPasswordCurrent’];
$passwordNew = $data[‘uPasswordNew’];
$passwordNewConfirm = $data[‘uPasswordNewConfirm’];
I’m not saving anything to the database. That is already handled by the Concrete core. What am I missing?
My apologies, I misinterpreted your previous post. What you are doing looks entirely reasonable.
The problem you will have is it will only work from that edit_profile page. What happens if someone uses the “I forgot my password” functionality from the login form?
I would also strongly suggest you don’t give any meaningful details in any error messages you would show. Saying something like “your new password has 8 characters in common with your old one” is a huge security risk.
I thought about the issue with the “I forgot my password” functionality. I’m checking to see if I have to disable/remove/change that functionality and rely on the administrator to reset it for the user. Also, the only message I’m providing the user is that they have to change at least 8 characters. I’m not telling them how many they have changed once submitted. Will that suffice? Thanks for the thoughtful feedback.
When the user only submits the new password you have absolutely no simple way of comparing it to the old one, so yes, your only option is to rely on people’s common sense.
Having said so, asking users who don’t remember their passwords to change at least 8 characters might be a tall order.
The only thing you could do is to make sure the new one is not identical to the old one as the hash would be the same if memory serves. You never know, it could happen.