This repository has been archived on 2026-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
2026-01-21 13:12:04 -05:00
..
2026-01-21 13:12:04 -05:00

Weak Password Hashing

Summary

BDServer stores passwords using unsalted SHA-512 hashes. Without a salt, identical passwords produce identical hashes, enabling rainbow table attacks. Without a work factor, SHA-512's speed makes brute-force attacks practical on modern hardware.

Vulnerability Details

Property Value
Type Insecure Password Storage
CVSS 7.5 (High)
CWE CWE-916 (Use of Password Hash With Insufficient Computational Effort), CWE-759 (Use of a One-Way Hash without a Salt)

Root Cause

Password hashing appears in three locations, all using the same pattern:

Login():

hashed = hashlib.sha512(password.encode("utf-8")).hexdigest()

Register():

hashed = hashlib.sha512(password.encode("utf-8")).hexdigest()

UpdatePassword():

old_hashed = hashlib.sha512(old_password.encode("utf-8")).hexdigest()
new_hashed = hashlib.sha512(new_password.encode("utf-8")).hexdigest()

This implementation has two fundamental problems:

No Salt

A salt is random data added to each password before hashing. Without it:

  • Identical passwords produce identical hashes. If two users choose "password123", their stored hashes are identical. An attacker who cracks one automatically cracks the other.

  • Rainbow tables work. Precomputed tables mapping common passwords to SHA-512 hashes allow instant lookups. A salt forces attackers to compute hashes per-user, making precomputation infeasible.

  • Credential stuffing is easier. Attackers can compare leaked hashes against databases from other breaches to identify password reuse.

No Work Factor

SHA-512 is designed for speed, not password storage. Modern GPUs can compute billions of SHA-512 hashes per second, making brute-force attacks practical.

Password hashing algorithms like Argon2 intentionally slow down hashing through configurable iteration counts and memory requirements. A work factor that takes 100ms per hash has negligible impact on legitimate logins but drastically slows brute-force attacks.

Remediation

Replace SHA-512 with Argon2, the winner of the 2015 Password Hashing Competition:

from argon2 import PasswordHasher

ph = PasswordHasher()

def hash_password(password: str) -> str:
    return ph.hash(password)

def verify_password(password: str, hashed: str) -> bool:
    try:
        ph.verify(hashed, password)
        return True
    except:
        return False

Migration Strategy

Existing users have SHA-512 hashes that cannot be converted without knowing the plaintext password. To migrate incrementally:

  1. Update the code to hash new passwords with Argon2
  2. On login, check if the stored hash is SHA-512 (128 hex characters) or Argon2 (starts with $argon2)
  3. If SHA-512 and login succeeds, rehash the password with Argon2 and update storage
  4. Over time, active users migrate automatically

Disclaimer

This assessment was performed on a best-effort basis against BDServer commit dc86854 and reflects the state of the software at the time of testing. The findings and remediations are provided for informational purposes and should be independently validated before implementation. This report does not guarantee all vulnerabilities have been identified, nor does it guarantee the suggested fixes will be effective in all environments.