UserFrosting
UserFrosting copied to clipboard
Store password hash type in users table
Right now, we guess the password hash type directly based on string length. This is sufficient for distinguishing the three types of hashes that we currently support (sha1, "legacy", and bcrypt), but if we want to support additional legacy hash types (or let devs import their own custom types), we need something better.
Some hashing schemes cannot be distinguished at all, so I propose a more explicit approach.
The users
table could simply store a hash_type
for each account. We would check this value on login to determine how to appropriately verify the user's password. Devs could define their own custom hash types, and then assign this custom hash type to any user accounts they import from legacy systems (Wordpress, UserCake, whatever).
One possible way would be to map hash types to custom hash verification classes:
[
'sha1' => 'Sha1Hasher',
'uf1' => 'UF1Hasher',
'bcrypt' => 'BcryptHasher',
...
]
Hash verification classes would need to implement one method, verify
, which determines whether or not a plaintext value matches a hashed value.
After a user is successfully logged in (password verified), their password will be rehashed to the application's default hashing function as usual.
For backwards compatibility, we could still have a special auto
hash type, which will tell UF to try to auto-detect the hash type based on its length (like we do now).
Instead of supporting multiple hash types, I know one framework (actually phpBB) when you import a user from another system (or older version), it sets a flags that force the user to reset and define a new password when sining back again, using email verification. Wouldn't that be easier and more secure, as it force dev to use UF hash of choice? If we selected that hash type, it's because it's good (unlike anything Wordpress related)
force dev to use UF hash of choice
Yes, but in the meantime, you still need to work with the legacy hash before the user signs in again. There's no point in forcing the user to create a new password - you have their plaintext password when they sign in, so you can rehash it to UF's hash of choice at that point.
After a user is successfully logged in (password verified), their password will be rehashed to the application's default hashing function as usual.
How exactly does the system currently work out what the hash type is? Trial and error? If its dependent on a configuration value, then we could just use that to migrate the database in one fell swoop.
Only edge case to consider would be if the developer decided to change the hash type setting at the same time (which I'm guessing would give the system grief at the moment anyway, which makes it a moot point).
There's no point in forcing the user to create a new password - you have their plaintext password when they sign in, so you can rehash it to UF's hash of choice at that point.
I disagree with this statement. I think there is good reason to force password reset, especially if the old system was using a weak hashing algorithm.
Wouldn't that be easier and more secure, as it force dev to use UF hash of choice?
How about if an organization's security policy already has specific requirements for allowed hashing algorithms? I think we need to allow for some flexibility here. Those that need to change it for specific purposes will, and the others will probably just leave the default.