Add PasswordPolicy to check the password isn't in the large blacklist

Add wikimedia/password-blacklist 0.1.3, which contains 100,000 common passwords

Bug: T151425
Change-Id: I80572fcee6d23ea04ad9ee683157bab9378b660e
Depends-On: I8aea5a44248da9bb9ff7b328679bff6fcf41750d
This commit is contained in:
Reedy 2018-02-26 00:56:52 +00:00 committed by Kunal Mehta
parent 0a8e16d7cf
commit 519ff1a402
7 changed files with 58 additions and 1 deletions

View file

@ -32,11 +32,13 @@ production.
* The 'GetPreferences' hook now receives an additional $context parameter.
* (T96041) __EXPECTUNUSEDCATEGORY__ on a category page causes the category
to be hidden on Special:UnusedCategories.
* Add PasswordPolicy to check the password isn't in the large blacklist.
* …
=== External library changes in 1.33 ===
==== New external libraries ====
* Added wikimedia/password-blacklist 0.1.3
* …
==== Changed external libraries ====

View file

@ -42,6 +42,7 @@
"wikimedia/html-formatter": "1.0.2",
"wikimedia/ip-set": "1.2.0",
"wikimedia/object-factory": "1.0.0",
"wikimedia/password-blacklist": "0.1.2",
"wikimedia/php-session-serializer": "1.0.6",
"wikimedia/purtle": "1.0.7",
"wikimedia/relpath": "2.1.1",

View file

@ -4520,6 +4520,8 @@ $wgCentralIdLookupProvider = 'local';
* commonly chosen. Set to integer n to ban the top n passwords.
* If you want to ban all common passwords on file, use the
* PHP_INT_MAX constant.
* - PasswordNotInLargeBlacklist - Password not in best practices list of
* 100,000 commonly used passwords.
* @since 1.26
*/
$wgPasswordPolicy = [
@ -4529,29 +4531,34 @@ $wgPasswordPolicy = [
'MinimumPasswordLengthToLogin' => 1,
'PasswordCannotMatchUsername' => true,
'PasswordCannotBePopular' => 25,
'PasswordNotInLargeBlacklist' => true,
],
'sysop' => [
'MinimalPasswordLength' => 8,
'MinimumPasswordLengthToLogin' => 1,
'PasswordCannotMatchUsername' => true,
'PasswordCannotBePopular' => 25,
'PasswordNotInLargeBlacklist' => true,
],
'interface-admin' => [
'MinimalPasswordLength' => 8,
'MinimumPasswordLengthToLogin' => 1,
'PasswordCannotMatchUsername' => true,
'PasswordCannotBePopular' => 25,
'PasswordNotInLargeBlacklist' => true,
],
'bot' => [
'MinimalPasswordLength' => 8,
'MinimumPasswordLengthToLogin' => 1,
'PasswordCannotMatchUsername' => true,
'PasswordNotInLargeBlacklist' => true,
],
'default' => [
'MinimalPasswordLength' => 1,
'PasswordCannotMatchUsername' => true,
'PasswordCannotMatchBlacklist' => true,
'MaximalPasswordLength' => 4096,
'PasswordNotInLargeBlacklist' => false,
],
],
'checks' => [
@ -4560,7 +4567,8 @@ $wgPasswordPolicy = [
'PasswordCannotMatchUsername' => 'PasswordPolicyChecks::checkPasswordCannotMatchUsername',
'PasswordCannotMatchBlacklist' => 'PasswordPolicyChecks::checkPasswordCannotMatchBlacklist',
'MaximalPasswordLength' => 'PasswordPolicyChecks::checkMaximalPasswordLength',
'PasswordCannotBePopular' => 'PasswordPolicyChecks::checkPopularPasswordBlacklist'
'PasswordCannotBePopular' => 'PasswordPolicyChecks::checkPopularPasswordBlacklist',
'PasswordNotInLargeBlacklist' => 'PasswordPolicyChecks::checkPasswordNotInLargeBlacklist',
],
];

View file

@ -22,6 +22,7 @@
use Cdb\Reader as CdbReader;
use MediaWiki\MediaWikiServices;
use Wikimedia\PasswordBlacklist;
/**
* Functions to check passwords against a policy requirement
@ -167,4 +168,25 @@ class PasswordPolicyChecks {
return $status;
}
/**
* Ensure the password isn't in the list of passwords blacklisted by the
* wikimedia/password-blacklist library
*
* @param bool $policyVal Whether to apply this policy
* @param User $user
* @param string $password
*
* @since 1.33
*
* @return Status
*/
public static function checkPasswordNotInLargeBlacklist( $policyVal, User $user, $password ) {
$status = Status::newGood();
if ( $policyVal && PasswordBlacklist\PasswordBlacklist::isBlacklisted( $password ) ) {
$status->error( 'passwordinlargeblacklist' );
}
return $status;
}
}

View file

@ -478,6 +478,7 @@
"passwordtooshort": "Passwords must be at least {{PLURAL:$1|1 character|$1 characters}}.",
"passwordtoolong": "Passwords cannot be longer than {{PLURAL:$1|1 character|$1 characters}}.",
"passwordtoopopular": "Commonly chosen passwords cannot be used. Please choose a password that is more difficult to guess.",
"passwordinlargeblacklist": "The password entered is in a list of very commonly used passwords. Please choose a more unique password.",
"password-name-match": "Your password must be different from your username.",
"password-login-forbidden": "The use of this username and password has been forbidden.",
"mailmypassword": "Reset password",
@ -4538,6 +4539,7 @@
"passwordpolicies-policy-passwordcannotmatchblacklist": "Password cannot match specifically blacklisted passwords",
"passwordpolicies-policy-maximalpasswordlength": "Password must be less than $1 {{PLURAL:$1|character|characters}} long",
"passwordpolicies-policy-passwordcannotbepopular": "Password cannot be {{PLURAL:$1|the popular password|in the list of $1 popular passwords}}",
"passwordpolicies-policy-passwordnotinlargeblacklist": "Password cannot be in the list of 100,000 most commonly used passwords.",
"easydeflate-invaliddeflate": "Content provided is not properly deflated",
"unprotected-js": "For security reasons JavaScript cannot be loaded from unprotected pages. Please only create javascript in the MediaWiki: namespace or as a User subpage"
}

View file

@ -681,6 +681,7 @@
"passwordtooshort": "This message is shown in [[Special:Preferences]] and [[Special:CreateAccount]].\n\nParameters:\n* $1 - the minimum number of characters in the password",
"passwordtoolong": "This message is shown in [[Special:Preferences]], [[Special:CreateAccount]], and [[Special:Userlogin]].\n\nParameters:\n* $1 - the maximum number of characters in the password",
"passwordtoopopular": "Shown if the user chooses a really popular password.",
"passwordinlargeblacklist": "Shown if the user chooses a very common password.",
"password-name-match": "Used as error message when password validity check failed.",
"password-login-forbidden": "Error message shown when the user has tried to log in using one of the special username/password combinations used for MediaWiki testing. (See [[mwr:75589]], [[mwr:75605]].)",
"mailmypassword": "Used as label for Submit button in [[Special:PasswordReset]].\n{{Identical|Reset password}}",
@ -4741,6 +4742,7 @@
"passwordpolicies-policy-passwordcannotmatchblacklist": "Password policy that enforces that passwords are not on a list of blacklisted passwords (often previously used during MediaWiki automated testing)",
"passwordpolicies-policy-maximalpasswordlength": "Password policy that enforces a maximum number of characters a password must be. $1 - maximum number of characters that a password can be",
"passwordpolicies-policy-passwordcannotbepopular": "Password policy that enforces that a password is not in a list of $1 number of \"popular\" passwords. $1 - number of popular passwords the password will be checked against",
"passwordpolicies-policy-passwordnotinlargeblacklist": "Password policy that enforces that a password is not in a list of 100,000 number of \"popular\" passwords.",
"easydeflate-invaliddeflate": "Error message if the content passed to easydeflate was not deflated (compressed) properly",
"unprotected-js": "Error message shown when trying to load javascript via action=raw that is not protected"
}

View file

@ -157,6 +157,26 @@ class PasswordPolicyChecksTest extends MediaWikiTestCase {
$this->assertSame( $expected, $status->isGood() );
}
public static function provideLargeBlacklist() {
return [
[ false, 'testpass' ],
[ false, 'password' ],
[ false, '12345' ],
[ true, 'DKn17egcA4' ],
[ true, 'testwikijenkinspass' ],
];
}
/**
* @covers PasswordPolicyChecks::checkPasswordNotInLargeBlacklist
* @dataProvider provideLargeBlacklist
*/
public function testCheckNotInLargeBlacklist( $expected, $password ) {
$user = User::newFromName( 'username' );
$status = PasswordPolicyChecks::checkPasswordNotInLargeBlacklist( true, $user, $password );
$this->assertSame( $expected, $status->isGood() );
}
/**
* Verify that all password policy description messages actually exist.
* Messages used on Special:PasswordPolicies