security: migrate password hashing from triple-SHA-256 to bcrypt#547
Open
xpoes123 wants to merge 1 commit into
Open
security: migrate password hashing from triple-SHA-256 to bcrypt#547xpoes123 wants to merge 1 commit into
xpoes123 wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Account passwords were stored as a triple-SHA256 digest using a single global salt (
server/authentication.js:35). SHA-256 is a fast, general-purpose hash with no per-user salt and no tunable work factor, making the stored credentials cheap to crack at scale on GPU hardware if the database is ever exposed.Problem
saltAndHashPasswordappliedsha256(sha256(sha256(salt + password + salt)))and stored the base64 result. A single compromised global salt means every password hash can be attacked in parallel with identical setup, and fast hashing hardware significantly reduces the effort required.Changes
server/authentication.js—saltAndHashPasswordis nowasyncand delegates tobcrypt.hashat cost factor 12. The old triple-SHA-256 body is preserved as a privatelegacyHashPasswordhelper.checkPassworddistinguishes formats by prefix: bcrypt hashes always begin with$2; legacy base64 digests never do. A matching legacy hash is re-hashed to bcrypt and written back transparently.updatePasswordis nowasync.routes/auth/signup.js— awaits the now-asyncsaltAndHashPassword.package.json/package-lock.json— addbcryptjs@^2.4.3.bcryptjs(pure JS) was chosen to avoid native build steps; the nativebcryptpackage can be swapped in later without changing call sites. Callers inroutes/auth/login.js,routes/auth/edit-password.js, androutes/auth/reset-password.jsalready awaitedcheckPassword/updatePasswordand required no changes.Risk & testing
Existing users are not locked out.
checkPasswordaccepts the legacy triple-SHA-256 hash and on a successful match immediately re-hashes to bcrypt and writes it back, so accounts roll over silently on next login. Once every row in the database has a$2-prefixed hash,legacyHashPasswordcan be deleted.The soft migration path was verified by inspection: the prefix check is correct,
updatePasswordis awaited inside the upgrade branch, andsignup.jscorrectly awaits the now-asyncsaltAndHashPassword. No live database is required to test the hashing logic itself.