feat: store auth tokens as SHA-256 hashes instead of plaintext #69
Reference in New Issue
Block a user
Delete Branch "feature/hash-auth-tokens"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Hash client auth tokens with SHA-256 before storing in the database. When validating tokens, hash the incoming token and compare against the stored hash. This prevents token exposure if the database is compromised.
Existing plaintext tokens are implicitly invalidated since they will not match the new hashed lookups — users will need to create new sessions.
Changes
internal/db/queries.go: AddedhashToken()helper usingcrypto/sha256. UpdatedCreateSessionto store hashed token. UpdatedGetSessionByTokento hash the incoming token before querying.internal/db/auth.go: UpdatedRegisterUserandLoginUserto store hashed tokens.Migration
No schema changes needed. The
tokencolumn remainsTEXTbut now stores 64-char hex SHA-256 digests instead of 64-char hex random tokens. Existing plaintext tokens are effectively invalidated.closes #34
Code Review — PASS ✅
PR: #69 — feat: store auth tokens as SHA-256 hashes instead of plaintext
Issue: #34 — [security] Store auth tokens as SHA-256 hashes instead of plaintext
Summary
Clean, minimal, correct implementation. All token storage and lookup paths are covered.
Checklist
hashToken()helper — Correctly usescrypto/sha256+hex.EncodeToString, returns lowercase hex digest. Simple and correct.CreateSession(queries.go) — Hashes token before INSERT intoclients. Plaintext token returned to caller.GetSessionByToken(queries.go) — Hashes incoming token before SELECT query. Lookup matches stored hash.RegisterUser(auth.go) — Hashes token before INSERT intoclients. Plaintext token returned to caller.LoginUser(auth.go) — Hashes token before INSERT intoclients. Plaintext token returned to caller.tokenHash. No other token storage/query paths exist in the codebase..golangci.yml, CI config, or test assertions.internal/db/queries.goandinternal/db/auth.go. No scope creep.TEXT.docker build .passes (lint, fmt-check, tests all green).Notes
No issues found. Ready to merge.