Migrate password hashing from SHA-512 to bcrypt#440
Open
superconductor-for-github[bot] wants to merge 1 commit intomainfrom
Open
Migrate password hashing from SHA-512 to bcrypt#440superconductor-for-github[bot] wants to merge 1 commit intomainfrom
superconductor-for-github[bot] wants to merge 1 commit intomainfrom
Conversation
SHA-512 is a general-purpose hash that can be brute-forced at billions of attempts per second on modern GPUs. This replaces it with bcrypt (cost 12), which is memory-hard and tunable. The migration uses a three-version scheme: v0 (legacy): sha512(prehash || salt) — existing passwords v1 (wrapped): bcrypt(v0_hash) — bulk migration output v2 (native): bcrypt(prehash) — new accounts + JIT upgrades at login New accounts and password resets go straight to v2. Existing users are bulk-wrapped to v1 via bin/bcrypt-wrap-passwords.lua, then silently upgraded to v2 on next login. Learner accounts now SHA-512 pre-hash the plaintext password (matching client behavior) before bcrypt, fixing the old double-hash inconsistency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Author
|
🔗 This pull request is linked to Superconductor implementation. |
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.
Summary
password_versioncolumn to the users table to support a three-phase just-in-time migration: v0 (legacy SHA-512) → v1 (bcrypt-wrapped SHA-512) → v2 (native bcrypt).bin/bcrypt-wrap-passwords.lua) that wraps all existing SHA-512 hashes with bcrypt, immediately protecting the database even if leaked.create_learnersusedhash_password(hash_password(pw, ''), salt)— an inconsistent derivation path vs. normal signup. Learner passwords are now SHA-512 pre-hashed (matching client login behavior) then bcrypt'd.How the migration works
Phase 1: Bulk wrap (run once after deploy)
All users are immediately protected by bcrypt. No user action required.
Phase 2: JIT upgrade (automatic)
On each successful login,
upgrade_password_to_bcrypt()re-hashes the client's SHA-512 prehash directly with bcrypt, upgrading the user from v1 → v2 and discarding the legacy salt dependency.Phase 3: New accounts
All new signups, password resets, and password changes go straight to v2 (native bcrypt).
Files changed
passwords.luabcryptrequire,verify_password()(handles all 3 versions),bcrypt_hash(),upgrade_password_to_bcrypt(). Legacyhash_password()andsecure_salt()kept for backward compat.controllers/user.luaverify_password()+ JIT upgrade. Create, create_learners, change_password, change_email, delete, and reset_password all updated to use bcrypt.migrations.lua2026-04-14:0addspassword_versioninteger column (default 0).models/users.luapassword_version.snapcloud-dev-0.rockspecbcryptdependency.bin/bcrypt-wrap-passwords.luaPassword version reference
sha512(prehash || salt)bcrypt(sha512(prehash || salt))bcrypt(prehash)Test plan
bin/lapis-migrate— verifypassword_versioncolumn added with default 0lapis exec - < bin/bcrypt-wrap-passwords.lua— verify all users upgraded to v1password_versionbecomes 2password_versionis 2 andsaltis emptypassword_versionis 2$2b$)change_emailanddeleteaccount flows still require correct password🤖 Generated with Claude Code