sec(auth): collapse MFA error paths to prevent enrollment status enumeration - #532
sec(auth): collapse MFA error paths to prevent enrollment status enumeration#532cristim wants to merge 2 commits into
Conversation
…eration Fixes #388: Login previously returned distinct error messages for "MFA code required" (correct password, MFA enabled, no code supplied) vs "invalid email or password" (wrong password). An attacker could submit the correct password with no MFA code and receive a different error, revealing both that the password was correct and that the account has MFA enabled. All MFA-related failure paths in verifyPasswordAndMFA now return the same generic "invalid email or password" message: - missing MFA code (was: "MFA code required") - wrong MFA code (was: "invalid MFA code") - MFA enabled but secret not configured (was: "MFA is enabled but not configured") Internal debug/warn logs still distinguish the paths for operator diagnostics. Updated tests in service_test.go and service_lockout_test.go to expect the generic message. Added TestLogin_MFAErrorsAreGeneric as a dedicated regression test covering all three error paths.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR unifies all MFA-related client-facing authentication failures to return "invalid email or password", updates internal logging, and adds/updates tests to ensure generic errors and correct failed-login and lockout behavior. ChangesMFA Error Enumeration Vulnerability Fix
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/auth/service.go`:
- Around line 191-203: The missing-MFA branches return a generic "invalid email
or password" without incrementing the failed-login counter; update the branches
that check req.MFACode == "" and user.MFASecret == "" to call
s.recordFailedLogin(ctx, user) (same as the invalid-MFA-code path) before
returning the generic error, preserving the existing logging and error text so
lockout counting is consistent for all MFA-related failures.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 321caa67-98fe-496c-8fc3-b5abb0e4f5dc
📒 Files selected for processing (3)
internal/auth/service.gointernal/auth/service_lockout_test.gointernal/auth/service_test.go
The missing-code and misconfigured-secret paths returned generic errors without calling recordFailedLogin, letting attackers avoid lockout by repeatedly omitting the MFA code. Add recordFailedLogin to both branches to match the invalid-code branch at line 207. Adds a regression test (TestLogin_AccountLockout_MFAMissingCodePath) that hammers the missing-code path and asserts lockout triggers after MaxFailedLoginAttempts. Fixes CodeRabbit finding on PR #532.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai resolve |
✅ Actions performedComments resolved. Approval is disabled; enable |
|
Superseded — base branch already implements the MFA-enrollment-enumeration fix (#388) with a cleaner approach: ErrMFARequired sentinel + recordFailedLogin already wired into both the password-fail and invalid-MFA-code branches in internal/auth/service.go. This PR's diff is now empty after rebase. |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
Fixes #388
Summary by CodeRabbit