I have been looking at the password hashing section of the Users module and found that it could do with a refresh for the current age. Please read my proposals and comment on whether you think this area is worthy of some work.
What the current system does right:
- It checks for a stronger hashing mechanism (CRYPT_EXT_DES)
- It uses per-record random salt
- It falls back to MD5 when the stronger hash mechanism isnât there - weaker security but portable, itâs guaranteed to hash
- It uses the built-in PHP crypt() method, rather than calling MD5 or SHA1 directly
What the current system does wrong:
- It stops looking if it finds CRYPT_EXT_DES and there are far stronger hash methods these days
- There is no way for the system to record the current method used for the hash that is saved in the database - it guesses the method by looking at the first character of the hash and the length of the hash
- It MD5âs the plaintext before passing it to the hashing mechanism - why?
Proposals:
2 things need to change. The first is fairly easy, which is to choose a stronger hash. I have created an experimental branch that uses openwall.comâs phpass - a portable password hasher that uses work units and strong hashing. I have tested it on a clean install and it works fine, for the initial user and created users.
The second is a lot harder. My simple testing works for fresh installs but a lot of people are going to have legacy installs with current users in the databases. suiteCRM needs to be updated to know what the hash method used is. This requires:
- Field password_hash_method VARCHAR(6) DEFAULT âLEGACYâ being added to the users table
- Field password_work_unit INT DEFAULT 8 being added to the users table
- Preferred hash method and work unit being added to the global options
- Code in the check areas to read the current hash method and use the correct check for logins
- Code in the hash areas to read the current preferred method from globals to use the current hash method
- Code on login to see if the preferred method has changed since the last user hash and re-hash the password using the current method - this is (should be) the only time we will have the plaintext in memory
Steps to test:
- Grab a fresh copy
- Grab PasswordHash.php and Users.php from my branch
- Run through the install as normal (fixing issue #45 if needed)
- Check your users table for the stronger hashes
Please let me know what you think - whether this work has merit and deserves further work to fully implement.