clusev/app/Livewire/Auth
boban 2520b87982 fix(security): flatten reset-timing residuals from Codex review
Follow-up hardening on top of 2171895 (which v0.9.2 shipped). That first pass
introduced a cost-12 bcrypt dummy that was *slower* than the real verify path —
a reverse timing oracle plus CPU-DoS amplification. Replace it with work that
mirrors the real path instead of exceeding it, and close the remaining query /
exception asymmetries:

- resetPassword(): resolve 2FA with a uniform lookup — always exactly one
  webauthn-existence query (even for a TOTP user, and for a missing account) so
  its presence/absence can't tell accounts apart. Every path now does one users
  lookup + one webauthn query + one Google2FA HMAC + one locked recovery-code
  transaction (real data when present, throwaway data otherwise).
- Split burnVerificationTime() into dummyTotpVerify() (HMAC) and
  dummyRecoveryLookup() (locked SELECT in a transaction); drop the bcrypt
  Hash::check entirely. A webauthn-only account spends an equivalent throwaway
  HMAC so its crypto cost matches a TOTP account.
- dummyRecoveryLookup() no longer catches DB errors: a DB failure must surface
  identically to the real useRecoveryCode(), else an outage is an error-response
  oracle (generic for unknown, 500 for a real account).
- sendResetLink(): report() the swallowed Throwable so a broken queue/token
  store is detectable instead of silently "succeeding" for every address.

Tests: ForgotPasswordTimingTest now asserts an identical (users,
webauthn_credentials) query fingerprint across TOTP, no-2FA, webauthn-only, and
unknown-email branches, plus queued-mail and rate-limiter parity. Codex re-review
verdict: clean (residual sub-microsecond crypto differences are below the
network/DB noise floor for this self-hosted single-admin threat model).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 19:43:40 +02:00
..
.gitkeep feat: scaffold — Dockerized Laravel 13 + Livewire 3 + Tailwind 4 + Reverb 2026-06-12 00:31:50 +02:00
ForgotPassword.php fix(security): flatten reset-timing residuals from Codex review 2026-06-15 19:43:40 +02:00
Login.php feat(i18n): bilingual foundation (DE/EN) + localize auth/dashboard/servers/fleet/account 2026-06-13 22:36:16 +02:00
PasswordChange.php feat(2fa): onboarding no longer forces 2FA (only password rotation) 2026-06-14 20:44:12 +02:00
ResetPassword.php fix(auth): toaster on auth pages + audit email-link resets 2026-06-14 17:07:52 +02:00
TwoFactorChallenge.php fix(2fa): TwoFactorSetup back to auth layout; exception-safe User::verifyTotp at all call sites 2026-06-14 21:40:15 +02:00
TwoFactorSetup.php fix(2fa): bound the backup-code reveal flag with a 10-minute TTL 2026-06-15 18:42:58 +02:00