feat: store auth tokens as SHA-256 hashes instead of plaintext #69

Merged
sneak merged 1 commits from feature/hash-auth-tokens into main 2026-03-10 12:44:29 +01:00
Collaborator

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: Added hashToken() helper using crypto/sha256. Updated CreateSession to store hashed token. Updated GetSessionByToken to hash the incoming token before querying.
  • internal/db/auth.go: Updated RegisterUser and LoginUser to store hashed tokens.

Migration

No schema changes needed. The token column remains TEXT but now stores 64-char hex SHA-256 digests instead of 64-char hex random tokens. Existing plaintext tokens are effectively invalidated.

closes #34

## 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`**: Added `hashToken()` helper using `crypto/sha256`. Updated `CreateSession` to store hashed token. Updated `GetSessionByToken` to hash the incoming token before querying. - **`internal/db/auth.go`**: Updated `RegisterUser` and `LoginUser` to store hashed tokens. ## Migration No schema changes needed. The `token` column remains `TEXT` but now stores 64-char hex SHA-256 digests instead of 64-char hex random tokens. Existing plaintext tokens are effectively invalidated. closes https://git.eeqj.de/sneak/chat/issues/34
clawbot added 1 commit 2026-03-10 12:07:16 +01:00
feat: store auth tokens as SHA-256 hashes instead of plaintext
All checks were successful
check / check (push) Successful in 4s
067e5403c4
Hash client 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.

Changes:
- Add hashToken() helper using crypto/sha256
- Hash tokens in CreateSession, RegisterUser, LoginUser before INSERT
- Hash incoming token in GetSessionByToken before SELECT
clawbot added the botneeds-review labels 2026-03-10 12:08:41 +01:00
Author
Collaborator

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 uses crypto/sha256 + hex.EncodeToString, returns lowercase hex digest. Simple and correct.
  • CreateSession (queries.go) — Hashes token before INSERT into clients. 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 into clients. Plaintext token returned to caller.
  • LoginUser (auth.go) — Hashes token before INSERT into clients. Plaintext token returned to caller.
  • No plaintext leaks — All 3 INSERT paths and the 1 SELECT path use tokenHash. No other token storage/query paths exist in the codebase.
  • No modifications to Makefile, .golangci.yml, CI config, or test assertions.
  • Only 2 files changedinternal/db/queries.go and internal/db/auth.go. No scope creep.
  • Migration note — PR body correctly documents that existing plaintext tokens are implicitly invalidated. No schema change needed since the column type remains TEXT.
  • docker build . passes (lint, fmt-check, tests all green).

Notes

  • The token column stores 64-char hex SHA-256 digests (same length as the previous 64-char hex random tokens), so no schema change is needed.
  • Existing sessions will be invalidated, which is acceptable for a pre-1.0 project and is documented in the PR description.

No issues found. Ready to merge.

## Code Review — PASS ✅ **PR:** [#69](https://git.eeqj.de/sneak/chat/pulls/69) — feat: store auth tokens as SHA-256 hashes instead of plaintext **Issue:** [#34](https://git.eeqj.de/sneak/chat/issues/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 uses `crypto/sha256` + `hex.EncodeToString`, returns lowercase hex digest. Simple and correct. - ✅ **`CreateSession`** (`queries.go`) — Hashes token before INSERT into `clients`. 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 into `clients`. Plaintext token returned to caller. - ✅ **`LoginUser`** (`auth.go`) — Hashes token before INSERT into `clients`. Plaintext token returned to caller. - ✅ **No plaintext leaks** — All 3 INSERT paths and the 1 SELECT path use `tokenHash`. No other token storage/query paths exist in the codebase. - ✅ **No modifications** to Makefile, `.golangci.yml`, CI config, or test assertions. - ✅ **Only 2 files changed** — `internal/db/queries.go` and `internal/db/auth.go`. No scope creep. - ✅ **Migration note** — PR body correctly documents that existing plaintext tokens are implicitly invalidated. No schema change needed since the column type remains `TEXT`. - ✅ **`docker build .`** passes (lint, fmt-check, tests all green). ### Notes - The token column stores 64-char hex SHA-256 digests (same length as the previous 64-char hex random tokens), so no schema change is needed. - Existing sessions will be invalidated, which is acceptable for a pre-1.0 project and is documented in the PR description. No issues found. Ready to merge.
clawbot added merge-ready and removed needs-reviewbot labels 2026-03-10 12:10:34 +01:00
sneak was assigned by clawbot 2026-03-10 12:10:42 +01:00
sneak merged commit 67446b36a1 into main 2026-03-10 12:44:29 +01:00
sneak deleted branch feature/hash-auth-tokens 2026-03-10 12:44:29 +01:00
Sign in to join this conversation.