Security: Switch password storage to password_hash() with legacy MD5 migration #685
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This pull request replaces the legacy MD5-based password handling with PHP's
password_hash()andpassword_verify()functions using PASSWORD_DEFAULT and ensures that newly set or changed passwords are always stored using the modern hashing API.For existing installations, legacy MD5 hashes are still accepted at login but, on successful authentication, the plaintext password is rehashed using PASSWORD_DEFAULT and the stored hash is updated. For modern hashes,
password_needs_rehash()is used after a successful login to transparently upgrade hashes if PASSWORD_DEFAULT changes in the future, while LDAP accounts remain unchanged and continue to rely on the existing LDAPUSER_PASSWORD placeholder and LDAP authentication flow, with password changes and resets still blocked for LDAP users.For new installations, the base schema now defines
user.passwordasVARCHAR(255), the installer’s schema upgrade path adds anALTER TABLEstep so existing databases are migrated to the same definition and the Security.MD documentation has been updated to reflect that OpenCATS now usespassword_hash()andpassword_verify()with PASSWORD_DEFAULT for password storage.Motivation
MD5 is no longer considered appropriate for storing user passwords, and modern PHP provides a well-established and actively maintained API for password hashing via
password_hash()andpassword_verify(), with PASSWORD_DEFAULT acting as a safe, forward-compatible algorithm selector that can adopt stronger algorithms over time without requiring further application changes.Integrating
password_needs_rehash()independently of the MD5 compatibility logic ensures that future changes to PASSWORD_DEFAULT or its options can be adopted at runtime without another invasive refactor and increasing the password column toVARCHAR(255)while updating Security.MD keeps schema and documentation aligned with current best practices and avoids further schema changes when PASSWORD_DEFAULT eventually moves to a stronger or longer hash format.