Feature #12136

Upgrade password hash function to a secure algorithm

Added by David Juhasz over 2 years ago. Updated 3 months ago.

Status:VerifiedStart date:04/11/2018
Priority:MediumDue date:
Assignee:-% Done:

0%

Category:Security
Target version:Release 2.6.0
Google Code Legacy ID: Tested version:2.4
Sponsored:No Requires documentation:

Description

Background
AtoM is currently using SHA1 + salt to hash passwords. SHA-1 is unsuitable for password hashing primarily because the hashing algorithm is too fast, making it economical to crack the password using brute force with modern hardware (see: About Secure Password Hashing "Speed" section). Modern hashing algorithms are designed to require a lot of CPU time and/or require a lot of memory to run to make it time consuming and expensive to crack the passwords using brute force. Most modern hashing algorithms also support a variable "work factor" which allows adjusting the hashing resource requirements based on contemporary hardware capabilities.

Which hashing algorithm should we use?

The OWASP Password Storage Cheat Sheet recommends one of (retrieved 2018-04-11):

  • Argon2[*7] is the winner of the password hashing competition and should be considered as your first choice for new applications;
  • PBKDF2 [*4] when FIPS certification or enterprise support on many platforms is required;
  • scrypt [*5] where resisting any/all hardware accelerated attacks is necessary but support isn’t.
  • bcrypt where PBKDF2 or scrypt support is not available.

The PHP password_hash() functions (available in PHP 5.5.0+ and PHP 7) supports bcrypt and Argon2 (7.2+) algorithms, and automatically generates a truly random salt. We should use the Argon2 algorithm if possible, but it is only available in PHP 7.2+ which may influence the final decision.

Upgrading AtoM hashes

To upgrade AtoM's password hashing we'll need change the hashing algorithm for new passwords, and also migrate existing passwords in the database. Because we only store the SHA1 password hash in the database, we don't have the plain text password available to create a new bcrypt or Argon2 hash. One method to work around this problem is to apply the new hashing algorithm (and a new salt) to hash the existing hash (ciphertext) value. This double-hashing strategy is easy to implement (just wrap the current SHA1 hashing function with a newer hashing function) but it does have the disadvantage of requiring us to store two different salts in the database.

We'll need to add a migration script to upgrade all existing passwords in the AtoM database, to avoid a mix of secure and insecure hashes.

[Edit 2018-04-11: fixed some typos and edited for clarity]
[Edit 2018-04-12: added migration script to requirements for upgrading hashes]


Related issues

Related to Access to Memory (AtoM) - Task #12004: Remove PHP mcrypt installation dependency Verified 02/27/2018

History

#1 Updated by David Juhasz over 2 years ago

  • Description updated (diff)

#2 Updated by David Juhasz over 2 years ago

  • Description updated (diff)

#3 Updated by David Juhasz over 2 years ago

Note, the LDAP authentication module is currently using password_hash() with bcrypt

To provide backwards compatibility with PHP < 5.5 this code is using a password compatibilty library, which currently doesn't work with PHP 7.1+ (see issue #12004)

If we decide to update the required PHP version to PHP 7.2 to use the Argon2 algorithm, then we can remove the password_compat library altogether.

#4 Updated by David Juhasz over 2 years ago

  • Related to Task #12004: Remove PHP mcrypt installation dependency added

#5 Updated by David Juhasz over 2 years ago

  • Description updated (diff)

#6 Updated by David Juhasz over 2 years ago

  • Description updated (diff)

#7 Updated by David Juhasz over 2 years ago

  • Description updated (diff)

#8 Updated by Dan Gillean over 2 years ago

  • Target version changed from Release 2.4.1 to Release 2.5.0

#9 Updated by Dan Gillean over 1 year ago

  • Target version deleted (Release 2.5.0)

#10 Updated by Dan Gillean 11 months ago

Note: there are some further password hashing enhancements in PHP 7.3 - slightly more robust versions of the argon algo have been supported. See:

In an ideal world, we would work on upgrading to PHP 7.3 as a precursor to this work. Otherwise, we should remember this when we upgrade PHP in the future and consider if we want to revisit this ticket at that time.

#11 Updated by Mike Cantelon 11 months ago

  • Status changed from New to Code Review

I've implemented password hashing in such a way that we can easily upgrade the algorithm (to PASSWORD_ARGON2ID for example) in subsequent releases if we'd like (and a user can change a config file to use PASSWORD_ARGON2ID right away if they'd like).

PR for CR: https://github.com/artefactual/atom/pull/1004

#12 Updated by Mike Cantelon 11 months ago

Something we could possibly add in the future, to support changes in hashing algorithms, is the ability to set a user-related property that will, once a user logs in, trigger the use of the password they've provided to redo their stored password hash.

Actually there should be a way to not need a user-related property to be manually set, too, given it should be easy to parse the algo/options from the password hash (here's an example of how it's encoded when stored as part of the hash string: "$argon2i$v=19$m=2048,t=4,p=3$"). If we can easily parse this info out there we can compare it to the current hash algo/options and trigger rehashing.

Edit: password_get_info should parse out the algo/options... https://www.php.net/manual/en/function.password-get-info.php

#14 Updated by Mike Cantelon 11 months ago

  • Status changed from Code Review to QA/Review

Merged into qa/2.6.x.

#15 Updated by Dan Gillean 11 months ago

  • Target version set to Release 2.6.0

So far, I've successfully created a new admin user via the CLI task, and a new editor via the UI, and have been able to log in with these new accounts. Anything else I should be testing on this?

#16 Updated by David Juhasz 11 months ago

  • Assignee set to Dan Gillean

Dan, I think one of the most important things to test is to upgrade a database (with users) from AtoM 2.5, and make sure you can still log in with the same password after the upgrade. The password hashes are rehashed using the new algorithm by running the tools:upgrade-sql task.

#17 Updated by Dan Gillean 11 months ago

Ah, good to know. I did reload my demo data and was able to log in w the demo account after the upgrade task was run, but I can test this a bit more explicitly.

#18 Updated by Mike Cantelon 11 months ago

  • Status changed from QA/Review to Code Review
  • Assignee deleted (Dan Gillean)

Fix to PHP version check and bump to PHP version number...

PR for CR: https://github.com/artefactual/atom/pull/1010

#19 Updated by Mike Cantelon 11 months ago

  • Status changed from Code Review to QA/Review

Not sure if this needs more QA review, but I merged the bump in the required PHP version to 7.2 as this needed it.

#20 Updated by Dan Gillean 10 months ago

Going to verify this now - It's been in place for a while, and I regularly load an older DB in, upgrade, and then successfully log in. Will reopen or create a new ticket if any further issues arise.

#21 Updated by Dan Gillean 10 months ago

  • Status changed from QA/Review to Verified

#22 Updated by Dan Gillean 3 months ago

  • Private changed from Yes to No

Also available in: Atom PDF