Mercurial > p > roundup > code
changeset 8239:6bd11a73f2ed
issue2551253. default hash is PBKDF2-SHA512.
The default password hashing algorithm has been upgraded to
PBKDF2-SHA512 from PBKDF2-SHA1. The default pbkdf2 rounds in the
config file has been changed to 250000.
Doc updated.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Mon, 30 Dec 2024 02:57:46 -0500 |
| parents | 05405220dc38 |
| children | 1189c742e4b3 |
| files | CHANGES.txt doc/upgrading.txt roundup/configuration.py roundup/password.py |
| diffstat | 4 files changed, 65 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES.txt Sun Dec 29 19:48:42 2024 -0500 +++ b/CHANGES.txt Mon Dec 30 02:57:46 2024 -0500 @@ -49,6 +49,13 @@ - issue2551383 - Setting same address via REST PUT command results in an error. Now the userauditor does not trigger an error if a user sets the primary address to the existing value. (John Rouillard) +- issue2551253 - Modify password PBKDF2 method to use SHA512. The + default password hashing algorithm has been upgraded to + PBKDF2-SHA512 from PBKDF2-SHA1. The default pbkdf2 rounds in the + config file has been changed to 250000. The admin should change it + manually if it is at 2 million. PBKDF2-SHA512 (PBKDF2S5) has been + available since release 2.3, but it required a manual step to make + it the default. (John Rouillard) Features:
--- a/doc/upgrading.txt Sun Dec 29 19:48:42 2024 -0500 +++ b/doc/upgrading.txt Mon Dec 30 02:57:46 2024 -0500 @@ -159,6 +159,41 @@ add the lines marked with ``+`` in the file in the location after check_main is assigned. +Modify config.ini password_pbkdf2_default_rounds setting (recommended) +---------------------------------------------------------------------- + +The method for hashing and storing passwords has been updated to use +PBKDF2 with SHA512 hash. This change was first introduced in Roundup +2.3 and is now the standard. If you previously added code in +interfaces.py for a `PBKDF2 upgrade`_ to enable PBKDF2S5, you can +remove that code now. + +SHA512 is a more secure hash, it requires fewer rounds to ensure +safety. The older PBKDF2-SHA1 needed around 2 million rounds. + +You should update the ``password_pbkdf2_default_rounds`` setting in +``config.ini`` to 250000. This value is higher than the OWASP +recommendation of 210000 from three years ago. If you don’t make this +change, logins will be slow, especially for REST or XMLRPC calls. + +See `PBKDF2 upgrade`_ for details on how to test the algorithm's +speed. We do not recommend reverting to the older SHA1 PBKDF2. If you +have to do so due to a slow CPU, you can add the following to your +tracker's ``interfaces.py``:: + + from roundup.password import Password + ## Use PBDKF2 (PBKDF2-SHA1) as default hash for passwords. + # That scheme is at the start of the deprecated_schemes list and ha + # to be removed. + Password.default_scheme = Password.deprecated_schemes.pop(0) + # Add PBKDF2S5 (PBKDF2-SHA512) as a valid scheme. Passwords + # using it will be rehashed to use PBDKF2. + Password.experimental_schemes[0] = "PBKDF2S5" + +If you proceed with this, you should set +``password_pbkdf2_default_rounds`` to 2 million or more rounds to keep +your hashed password database secure in case it gets stolen. + Defusedxml support improves XMLRPC security (optional) ------------------------------------------------------ @@ -1292,6 +1327,8 @@ .. _recommended setting of 1,300,000: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 +.. _PBKDF2 upgrade: + Upgrade to PBKDF2-SHA512 from current PBKDF2-SHA1 (recommended) ---------------------------------------------------------------
--- a/roundup/configuration.py Sun Dec 29 19:48:42 2024 -0500 +++ b/roundup/configuration.py Mon Dec 30 02:57:46 2024 -0500 @@ -1139,10 +1139,11 @@ "get the error 'Error: field larger than field limit' during\n" "import."), (IntegerNumberGeqZeroOption, 'password_pbkdf2_default_rounds', - '2000000', + '250000', "Sets the default number of rounds used when encoding passwords\n" - "using the PBKDF2 scheme. Set this to a higher value on faster\n" - "systems which want more security.\n" + "using any PBKDF2 scheme. Set this to a higher value on faster\n" + "systems which want more security. Use a minimum of 250000\n" + "for PBKDF2-SHA512 which is the default hash in Roundup 2.5.\n" "PBKDF2 (Password-Based Key Derivation Function) is a\n" "password hashing mechanism that derives hash from the\n" "password and a random salt. For authentication this process\n"
--- a/roundup/password.py Sun Dec 29 19:48:42 2024 -0500 +++ b/roundup/password.py Mon Dec 30 02:57:46 2024 -0500 @@ -331,7 +331,7 @@ version only reads the encryption scheme from the given encrypted password. """ - default_scheme = 'PBKDF2' # new encryptions use this scheme + default_scheme = 'PBKDF2S5' # new encryptions use this scheme pwre = re.compile(r'{(\w+)}(.+)') def __init__(self, encrypted=''): @@ -394,12 +394,12 @@ 1 """ - deprecated_schemes = ["SSHA", "SHA", "MD5", "plaintext"] + deprecated_schemes = ["PBKDF2", "SSHA", "SHA", "MD5", "plaintext"] if crypt: # place just before plaintext if crypt is available deprecated_schemes.insert(-1, "crypt") - experimental_schemes = ["PBKDF2S5"] - known_schemes = ["PBKDF2"] + experimental_schemes + \ + experimental_schemes = [] + known_schemes = ["PBKDF2S5"] + experimental_schemes + \ deprecated_schemes def __init__(self, plaintext=None, scheme=None, encrypted=None, @@ -442,6 +442,19 @@ new_rounds = 1000 if rounds < int(new_rounds): return True + + if (self.scheme == "PBKDF2S5"): + new_rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS + if ("pytest" in sys.modules and + "PYTEST_CURRENT_TEST" in os.environ): + if ("PYTEST_USE_CONFIG" in os.environ): + new_rounds = config.PASSWORD_PBKDF2_DEFAULT_ROUNDS + else: + # for testing + new_rounds = 1000 + if rounds < int(new_rounds): + return True + return False def unpack(self, encrypted, scheme=None, strict=False, config=None):
