-
Notifications
You must be signed in to change notification settings - Fork 927
PM-27902: Logout user after successful master password reset #6133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When a user updates their master password due to policy requirements, they must be logged out to ensure security compliance. Previously, the user remained logged in and could immediately access their vault. This fix removes the manual clearing of forcePasswordResetReason and instead calls logout() after the password update succeeds. The logout operation atomically clears all user state (including the reset reason) and forces re-authentication with the new password. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Claude finished @SaintPatrck's task —— View job PR Review: Logout After Master Password ResetSummaryThis PR successfully addresses a critical security vulnerability where users remained logged in after forced password resets, bypassing re-authentication requirements. The implementation is clean, follows established patterns, and includes proper test coverage. Security Assessment ✅Vulnerability Fixed:
Implementation Correctness:
Architecture Compliance ✅MVVM + Repository Pattern:
Error Handling:
Dependency Injection:
Code Quality ✅Style Compliance:
Test Coverage:
Detailed FindingsI've created inline comments on specific lines with the following observations:
RecommendationApprove with minor suggestions. The security fix is correct and complete. The inline comments contain optional enhancements that would improve documentation and test coverage, but are not blocking issues. Key Validation Points:
|
|
|
||
| // Log out the user after successful password reset. | ||
| // This clears all user state including forcePasswordResetReason. | ||
| logout(reason = LogoutReason.PasswordReset) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security Implementation Verified ✅
The logout call correctly addresses the security vulnerability. After successful password update:
- Master password hash is updated in disk storage (line 1035-1038)
logout(LogoutReason.PasswordReset)atomically clears all user state includingforcePasswordResetReason- User must re-authenticate with the new password
This prevents the original issue where users remained logged in and could immediately access the vault without re-authentication.
Potential Issue - Return After Logout:
The function returns ResetPasswordResult.Success after calling logout() (line 1046). Since logout() delegates to userLogoutManager.logout() which clears user state, consider whether the return value will be properly received by the caller before state is cleared.
Based on the code flow:
logout()is synchronous (line 726-732)- It immediately triggers state clearing
- The return happens in the same execution context
This should work correctly, but verify that the caller (likely ResetPasswordViewModel) properly handles the success result before the logout navigation occurs.
| /** | ||
| * Indicates that the logout is happening because the user reset their master password. | ||
| */ | ||
| data object PasswordReset : LogoutReason() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation Enhancement 📝
The KDoc accurately describes the logout reason. Consider adding a note about the security context:
Suggested enhancement
/**
* Indicates that the logout is happening because the user reset their master password.
* This ensures re-authentication with the new password before vault access is granted,
* maintaining security for policy-enforced password resets.
*/
data object PasswordReset : LogoutReason()This clarifies the security intent for future maintainers, though the current documentation is sufficient.
| verify { | ||
| userLogoutManager.logout( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test Coverage Verified ✅
The test correctly verifies that logout() is called with LogoutReason.PasswordReset after successful password reset. This ensures the security fix is properly validated.
Minor Enhancement Suggestion:
Consider adding a test case for the scenario where logout() is NOT called when password reset fails (e.g., in the existing resetPassword Failure should return Error test at line 5085). This would verify that logout only happens on success:
Example assertion to add to failure test
verify(exactly = 0) {
userLogoutManager.logout(
userId = any(),
reason = any(),
)
}This is a minor enhancement - the current test coverage is sufficient to validate the fix.
|
Great job! No new security vulnerabilities introduced in this pull request |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6133 +/- ##
==========================================
- Coverage 84.97% 84.97% -0.01%
==========================================
Files 723 723
Lines 52746 52744 -2
Branches 7649 7649
==========================================
- Hits 44822 44820 -2
Misses 5250 5250
Partials 2674 2674 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
aj-rosado
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
|
Thanks @aj-rosado and @david-livefront |
…en#6133) Co-authored-by: Claude <noreply@anthropic.com>

🎟️ Tracking
https://bitwarden.atlassian.net/browse/PM-27902
📔 Objective
Fixes a critical security issue where users remained logged in after updating their master password due to policy requirements. This allowed users to immediately access their vault with the new password without re-authentication, bypassing the security intent of forced password resets.
Root Cause
When
AuthRepositoryImpl.resetPassword()succeeded, it cleared theforcePasswordResetReasonflag but never triggered logout. The reactive navigation system (RootNavViewModel) detected that the reset reason was cleared and the vault was still unlocked, causing navigation to the vault screen instead of the login screen.Solution
This fix removes the manual clearing of
forcePasswordResetReasonand instead callslogout()after the password update succeeds. The logout operation atomically clears all user state (including the reset reason) and forces re-authentication with the new password.Additionally, a new
LogoutReason.PasswordResetenum value was added to provide semantic clarity in audit logs and analytics, distinguishing password reset logouts from other security-related logout events.Changes
logout(LogoutReason.PasswordReset)callPasswordResetenum value for audit trail clarityExpected Flow After Fix
logout(PasswordReset)→ clears all user state📸 Screenshots
Screen_recording_20251106_202236.mp4