Skip to content

Improve password hashing: use scrypt with dedicated salt column #107

@Soulike

Description

@Soulike

Problem

Currently, password hashing uses the username as the salt with SHA-512:

sha512(username + password)

This has security weaknesses:

  • Predictable salt: Usernames are public and known to attackers, making precomputed attacks easier.
  • No uniqueness guarantee: If a user changes their password, the salt remains the same.
  • Weak algorithm: SHA-512 is a general-purpose hash — too fast for password hashing, vulnerable to GPU brute-force.

Proposal

  1. Add a dedicated salt column to the users table (random bytes per user, generated via crypto.randomBytes).
  2. Replace SHA-512 with crypto.scrypt (built into Node.js, no extra dependency needed).
    • scrypt is intentionally slow with a configurable cost factor.
    • scrypt is memory-hard, resistant to GPU/ASIC attacks.
  3. Store the scrypt-derived hash in the password column and the random salt in the salt column.

Migration Plan

  1. Add the salt column to the users table (nullable initially).
  2. During login, check if the user has a salt value:
    • No salt (legacy user): verify with the old sha512(username + password) scheme. On success, re-hash with scrypt + random salt, and store both.
    • Has salt (migrated user): verify with scrypt.
  3. Once all active users have been migrated, make the salt column non-nullable and remove the legacy fallback.

Affected Files

  • apps/server/auth/src/tasks/check-user-task.ts
  • modules/server/database/src/tables/user-table.ts
  • modules/universal/classes/src/User.ts (add optional salt field)
  • Database schema (add salt column to users table)

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions