fix(server): login timing pad, 409 on register race, avatar magic-byte check #144

Merged
funman300 merged 1 commits from fix/server-low-findings into master 2026-07-07 03:15:04 +00:00
Owner

Closes the three actionable server Low findings from today's review:

  • #139 — unknown-username logins verify a static bcrypt dummy hash so both failure paths cost the same (kills the user-enumeration timing oracle).
  • #140 — register maps unique-constraint violations to 409 UsernameTaken; the DB constraint arbitrates the concurrent case.
  • #141 — avatar uploads are magic-byte checked against the declared type before the extension is stored.

Unit tests cover all four image signatures (real, spoofed, truncated) and the dummy hash. Workspace clippy --all-targets -D warnings clean; full test suite green.

Closes #139
Closes #140
Closes #141

🤖 Generated with Claude Code

Closes the three actionable server Low findings from today's review: - **#139** — unknown-username logins verify a static bcrypt dummy hash so both failure paths cost the same (kills the user-enumeration timing oracle). - **#140** — register maps unique-constraint violations to 409 `UsernameTaken`; the DB constraint arbitrates the concurrent case. - **#141** — avatar uploads are magic-byte checked against the declared type before the extension is stored. Unit tests cover all four image signatures (real, spoofed, truncated) and the dummy hash. Workspace clippy `--all-targets -D warnings` clean; full test suite green. Closes #139 Closes #140 Closes #141 🤖 Generated with [Claude Code](https://claude.com/claude-code)
funman300 added 1 commit 2026-07-07 03:15:03 +00:00
Closes the three actionable server Low findings from the 2026-07-06
review:

- #139: unknown-username logins now verify against a static bcrypt
  dummy hash so both failure paths pay the same cost — response timing
  no longer reveals which usernames exist.
- #140: register maps a unique-constraint violation to UsernameTaken
  (409) — the SELECT pre-check stays as the friendly fast path, the
  constraint is the arbiter for the concurrent case.
- #141: avatar uploads must start with the magic bytes of the declared
  image type; the stored extension (which decides how the file is
  re-served) is now backed by content, not the Content-Type header.

Unit tests: real/spoofed/truncated signatures for all four formats,
and the dummy hash's validity at BCRYPT_COST.

Closes #139
Closes #140
Closes #141

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
funman300 merged commit f0336d784d into master 2026-07-07 03:15:04 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: funman300/Ferrous-Solitaire#144