From d2033d4c927929e4db59e5a2e8fd8eb8037375c3 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Wed, 18 Jan 2023 20:33:39 -0500 Subject: [PATCH] Allow colon in password - It was disallowed because of a too strict intepretation of RFC2617 --- src/Model/User.php | 6 +++--- src/Module/OAuth/Token.php | 5 ++++- src/Module/Security/PasswordTooLong.php | 2 +- src/Module/Settings/Account.php | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Model/User.php b/src/Model/User.php index 35ea835b3..75b913250 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -757,7 +757,7 @@ class User } /** - * Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:). + * Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters. * * Password length is limited to 72 characters if the current default password hashing algorithm is Blowfish. * From the manual: "Using the PASSWORD_BCRYPT as the algorithm, will result in the password parameter being @@ -770,7 +770,7 @@ class User */ public static function getPasswordRegExp(string $delimiter = null): string { - $allowed_characters = '!"#$%&\'()*+,-./;<=>?@[\]^_`{|}~'; + $allowed_characters = ':!"#$%&\'()*+,-./;<=>?@[\]^_`{|}~'; if ($delimiter) { $allowed_characters = preg_quote($allowed_characters, $delimiter); @@ -804,7 +804,7 @@ class User } if (!preg_match('/' . self::getPasswordRegExp('/') . '/', $password)) { - throw new Exception(DI::l10n()->t('The password can\'t contain accentuated letters, white spaces or colons (:)')); + throw new Exception(DI::l10n()->t("The password can't contain white spaces nor accentuated letters")); } return self::updatePasswordHashed($uid, self::hashPassword($password)); diff --git a/src/Module/OAuth/Token.php b/src/Module/OAuth/Token.php index 7481bf75f..6f68215cc 100644 --- a/src/Module/OAuth/Token.php +++ b/src/Module/OAuth/Token.php @@ -61,7 +61,10 @@ class Token extends BaseApi } if (empty($request['client_id']) && substr($authorization, 0, 6) == 'Basic ') { - $datapair = explode(':', base64_decode(trim(substr($authorization, 6)))); + // Per RFC2617, usernames can't contain a colon but password can, + // so we cut on the first colon to obtain the username and the password + // @see https://www.rfc-editor.org/rfc/rfc2617#section-2 + $datapair = explode(':', base64_decode(trim(substr($authorization, 6))), 2); if (count($datapair) == 2) { $request['client_id'] = $datapair[0]; $request['client_secret'] = $datapair[1]; diff --git a/src/Module/Security/PasswordTooLong.php b/src/Module/Security/PasswordTooLong.php index 1934556b3..53fafea41 100644 --- a/src/Module/Security/PasswordTooLong.php +++ b/src/Module/Security/PasswordTooLong.php @@ -98,7 +98,7 @@ class PasswordTooLong extends \Friendica\BaseModule '$return_url' => $request['return_url'] ?? '', '$password_current' => ['password_current', $this->l10n->t('Current Password:'), '', $this->l10n->t('Your current password to confirm the changes'), 'required', 'autocomplete="off"'], - '$password' => ['password', $this->l10n->t('New Password:'), '', $this->l10n->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:).') . ' ' . $this->l10n->t('Password length is limited to 72 characters.'), 'required', 'autocomplete="off"', User::getPasswordRegExp()], + '$password' => ['password', $this->l10n->t('New Password:'), '', $this->l10n->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters.') . ' ' . $this->l10n->t('Password length is limited to 72 characters.'), 'required', 'autocomplete="off"', User::getPasswordRegExp()], '$password_confirm' => ['password_confirm', $this->l10n->t('Confirm:'), '', '', 'required', 'autocomplete="off"'], ]); diff --git a/src/Module/Settings/Account.php b/src/Module/Settings/Account.php index df8d41519..f8f65e720 100644 --- a/src/Module/Settings/Account.php +++ b/src/Module/Settings/Account.php @@ -549,7 +549,7 @@ class Account extends BaseSettings $notify_type = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'notify_type'); - $passwordRules = DI::l10n()->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces, accentuated letters and colon (:).') + $passwordRules = DI::l10n()->t('Allowed characters are a-z, A-Z, 0-9 and special characters except white spaces and accentuated letters.') . (PASSWORD_DEFAULT === PASSWORD_BCRYPT ? ' ' . DI::l10n()->t('Password length is limited to 72 characters.') : ''); $tpl = Renderer::getMarkupTemplate('settings/account.tpl');