Skip to content

Commit d382804

Browse files
Moves User::validatePassword() to Security::validatePassword()
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
1 parent e0b073b commit d382804

6 files changed

Lines changed: 87 additions & 87 deletions

File tree

Sources/Actions/Register2.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ public static function registerMember(array &$reg_options, bool $return_errors =
514514

515515
// Now perform hard password validation as required.
516516
if (!empty($reg_options['check_password_strength']) && $reg_options['password'] != '') {
517-
$password_error = User::validatePassword($reg_options['password'], $reg_options['username'], [$reg_options['email']]);
517+
$password_error = Security::validatePassword($reg_options['password'], $reg_options['username'], [$reg_options['email']]);
518518

519519
// Password isn't legal?
520520
if ($password_error != null) {

Sources/Actions/Reminder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public function setPassword2(): void
242242
$this->loadMember();
243243

244244
// Is the password actually valid?
245-
$passwordError = User::validatePassword($_POST['passwrd1'], $this->member->username, [$this->member->email]);
245+
$passwordError = Security::validatePassword($_POST['passwrd1'], $this->member->username, [$this->member->email]);
246246

247247
// What - it's not?
248248
if ($passwordError != null) {
@@ -380,7 +380,7 @@ public function secretAnswer2(): void
380380
}
381381

382382
// Make sure they have a strong enough password.
383-
$passwordError = User::validatePassword($_POST['passwrd1'], $this->member->username, [$this->member->email]);
383+
$passwordError = Security::validatePassword($_POST['passwrd1'], $this->member->username, [$this->member->email]);
384384

385385
// Invalid?
386386
if ($passwordError != null) {

Sources/Profile.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ public function loadStandardFields(bool $force_reload = false)
563563
&& $_POST['passwrd1'] != ''
564564
&& isset($_POST['passwrd2'])
565565
&& $_POST['passwrd1'] == $_POST['passwrd2']
566-
&& User::validatePassword(Utils::htmlspecialcharsDecode($_POST['passwrd1']), $value, [$this->name, User::$me->username, User::$me->name, User::$me->email]) == null
566+
&& Security::validatePassword(Utils::htmlspecialcharsDecode($_POST['passwrd1']), $value, [$this->name, User::$me->username, User::$me->name, User::$me->email]) == null
567567
) {
568568
$reset_password = false;
569569
}
@@ -605,7 +605,7 @@ public function loadStandardFields(bool $force_reload = false)
605605
}
606606

607607
// Let's get the validation function into play...
608-
$passwordErrors = User::validatePassword(Utils::htmlspecialcharsDecode($value), $this->username, [$this->name, User::$me->username, User::$me->name, User::$me->email]);
608+
$passwordErrors = Security::validatePassword(Utils::htmlspecialcharsDecode($value), $this->username, [$this->name, User::$me->username, User::$me->name, User::$me->email]);
609609

610610
// Were there errors?
611611
if ($passwordErrors != null) {

Sources/Security.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,71 @@ public static function generateValidationCode(): string
9898
return bin2hex(random_bytes(5));
9999
}
100100

101+
/**
102+
* Checks whether a password meets the current forum rules.
103+
*
104+
* Called when registering and when choosing a new password in the profile.
105+
*
106+
* If password checking is enabled, will check that none of the words in
107+
* $restrict_in appear in the password.
108+
*
109+
* Returns an error identifier if the password is invalid, or null if valid.
110+
*
111+
* @param string $password The desired password.
112+
* @param string $username The username.
113+
* @param array $restrict_in An array of restricted strings that cannot be
114+
* part of the password (email address, username, etc.)
115+
* @return null|string Null if valid or a string indicating the problem.
116+
*/
117+
public static function validatePassword(string $password, string $username, array $restrict_in = []): ?string
118+
{
119+
// Perform basic requirements first.
120+
if (Utils::entityStrlen($password) < (empty(Config::$modSettings['password_strength']) ? 4 : 8)) {
121+
return 'short';
122+
}
123+
124+
// Maybe we need some more fancy password checks.
125+
$pass_error = '';
126+
127+
IntegrationHook::call('integrate_validatePassword', [$password, $username, $restrict_in, &$pass_error]);
128+
129+
if (!empty($pass_error)) {
130+
return $pass_error;
131+
}
132+
133+
// Is this enough?
134+
if (empty(Config::$modSettings['password_strength'])) {
135+
return null;
136+
}
137+
138+
// Otherwise, perform the medium strength test - checking if password appears in the restricted string.
139+
if (preg_match('~\b' . preg_quote($password, '~') . '\b~', implode(' ', $restrict_in))) {
140+
return 'restricted_words';
141+
}
142+
143+
if (Utils::entityStrpos($password, $username) !== false) {
144+
return 'restricted_words';
145+
}
146+
147+
// If just medium, we're done.
148+
if (Config::$modSettings['password_strength'] == 1) {
149+
return null;
150+
}
151+
152+
// Check for both numbers and letters.
153+
$good = preg_match('~\p{N}~u', $password) && preg_match('~\p{L}~u', $password);
154+
155+
// If there are any letters from bicameral scripts (Latin, Greek, etc.),
156+
// check that there are both lowercase and uppercase letters present.
157+
// Note: If the password only contains letters from a unicameral script
158+
// (Arabic, Thai, etc.), this requirement is not applicable.
159+
if (Utils::strtoupper($password) !== ($lower_password = Utils::strtolower($password))) {
160+
$good &= $password !== $lower_password;
161+
}
162+
163+
return $good ? null : 'chars';
164+
}
165+
101166
/**
102167
* Check if a specific confirm parameter was given.
103168
*

Sources/Subs-Compat.php

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8823,6 +8823,23 @@ function memoryReturnBytes(string $val): int
88238823
* Begin SMF\Security
88248824
********************/
88258825

8826+
/**
8827+
* Checks whether a password meets the current forum rules
8828+
* - called when registering/choosing a password.
8829+
* - checks the password obeys the current forum settings for password strength.
8830+
* - if password checking is enabled, will check that none of the words in restrict_in appear in the password.
8831+
* - returns an error identifier if the password is invalid, or null.
8832+
*
8833+
* @param string $password The desired password
8834+
* @param string $username The username
8835+
* @param array $restrict_in An array of restricted strings that cannot be part of the password (email address, username, etc.)
8836+
* @return null|string Null if valid or a string indicating what the problem was
8837+
*/
8838+
function validatePassword(string $password, string $username, array $restrict_in = []): ?string
8839+
{
8840+
return SMF\Security::validatePassword($password, $username, $restrict_in);
8841+
}
8842+
88268843
/**
88278844
* Generate a random validation code.
88288845
*
@@ -10369,23 +10386,6 @@ function deleteMembers(int|array $users, bool $check_not_admin = false): void
1036910386
SMF\User::delete($users, $check_not_admin);
1037010387
}
1037110388

10372-
/**
10373-
* Checks whether a password meets the current forum rules
10374-
* - called when registering/choosing a password.
10375-
* - checks the password obeys the current forum settings for password strength.
10376-
* - if password checking is enabled, will check that none of the words in restrict_in appear in the password.
10377-
* - returns an error identifier if the password is invalid, or null.
10378-
*
10379-
* @param string $password The desired password
10380-
* @param string $username The username
10381-
* @param array $restrict_in An array of restricted strings that cannot be part of the password (email address, username, etc.)
10382-
* @return null|string Null if valid or a string indicating what the problem was
10383-
*/
10384-
function validatePassword(string $password, string $username, array $restrict_in = []): ?string
10385-
{
10386-
return SMF\User::validatePassword($password, $username, $restrict_in);
10387-
}
10388-
1038910389
/**
1039010390
* Checks a username obeys a load of rules
1039110391
*

Sources/User.php

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3637,71 +3637,6 @@ public static function delete(int|array $users, bool $check_not_admin = false, b
36373637
Logging::logActions($log_changes);
36383638
}
36393639

3640-
/**
3641-
* Checks whether a password meets the current forum rules.
3642-
*
3643-
* Called when registering and when choosing a new password in the profile.
3644-
*
3645-
* If password checking is enabled, will check that none of the words in
3646-
* $restrict_in appear in the password.
3647-
*
3648-
* Returns an error identifier if the password is invalid, or null if valid.
3649-
*
3650-
* @param string $password The desired password.
3651-
* @param string $username The username.
3652-
* @param array $restrict_in An array of restricted strings that cannot be
3653-
* part of the password (email address, username, etc.)
3654-
* @return null|string Null if valid or a string indicating the problem.
3655-
*/
3656-
public static function validatePassword(string $password, string $username, array $restrict_in = []): ?string
3657-
{
3658-
// Perform basic requirements first.
3659-
if (Utils::entityStrlen($password) < (empty(Config::$modSettings['password_strength']) ? 4 : 8)) {
3660-
return 'short';
3661-
}
3662-
3663-
// Maybe we need some more fancy password checks.
3664-
$pass_error = '';
3665-
3666-
IntegrationHook::call('integrate_validatePassword', [$password, $username, $restrict_in, &$pass_error]);
3667-
3668-
if (!empty($pass_error)) {
3669-
return $pass_error;
3670-
}
3671-
3672-
// Is this enough?
3673-
if (empty(Config::$modSettings['password_strength'])) {
3674-
return null;
3675-
}
3676-
3677-
// Otherwise, perform the medium strength test - checking if password appears in the restricted string.
3678-
if (preg_match('~\b' . preg_quote($password, '~') . '\b~', implode(' ', $restrict_in))) {
3679-
return 'restricted_words';
3680-
}
3681-
3682-
if (Utils::entityStrpos($password, $username) !== false) {
3683-
return 'restricted_words';
3684-
}
3685-
3686-
// If just medium, we're done.
3687-
if (Config::$modSettings['password_strength'] == 1) {
3688-
return null;
3689-
}
3690-
3691-
// Check for both numbers and letters.
3692-
$good = preg_match('~\p{N}~u', $password) && preg_match('~\p{L}~u', $password);
3693-
3694-
// If there are any letters from bicameral scripts (Latin, Greek, etc.),
3695-
// check that there are both lowercase and uppercase letters present.
3696-
// Note: If the password only contains letters from a unicameral script
3697-
// (Arabic, Thai, etc.), this requirement is not applicable.
3698-
if (Utils::strtoupper($password) !== ($lower_password = Utils::strtolower($password))) {
3699-
$good &= $password !== $lower_password;
3700-
}
3701-
3702-
return $good ? null : 'chars';
3703-
}
3704-
37053640
/**
37063641
* Checks whether a username obeys a load of rules.
37073642
*

0 commit comments

Comments
 (0)