diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 32ebfcb43ef77..2091c450b7748 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc @@ -2334,6 +2334,65 @@ TEST_F(PasswordAutofillManagerTest, PasswordRecoveryState::kRegularFlow); } +// POC: kBackupPasswordEntry hover-preview bypasses the +// IsBiometricAuthenticationBeforeFillingEnabled() gate that protects the +// sibling kPasswordEntry preview path. +// +// When the user has enabled "Use your screen lock when filling passwords" +// (kBiometricAuthenticationBeforeFilling pref, Mac/Win/ChromeOS only), +// hovering a regular kPasswordEntry row in the autofill popup does NOT send +// the cleartext password to the renderer (PreviewSuggestion() at +// password_autofill_manager.cc:764-767 returns early). However, hovering a +// kBackupPasswordEntry row takes the branch at +// password_autofill_manager.cc:259-266 which calls +// driver->PreviewSuggestion(username, backup_password) directly with NO +// biometric check, leaking the cleartext backup password into renderer memory +// before the user passes OS reauth. +// +// This test mocks IsBiometricAuthenticationBeforeFillingEnabled()==true (so it +// runs on all platforms including Linux) and demonstrates: +// (a) CONTROL: regular kPasswordEntry hover -> driver NOT called (gated). +// (b) BUG: kBackupPasswordEntry hover -> driver IS called with +// cleartext backup password (gate bypassed). +TEST_F(PasswordAutofillManagerTest, + POC_BackupPasswordPreviewBypassesBiometricGate) { + TestPasswordManagerClient client; + // Simulate the user having enabled biometric-auth-before-filling + // (Mac/Win/ChromeOS opt-in pref). + ON_CALL(*client.GetPasswordFeatureManager(), + IsBiometricAuthenticationBeforeFillingEnabled) + .WillByDefault(Return(true)); + InitializePasswordAutofillManager(&client, nullptr); + + // ------------------------------------------------------------------------- + // (a) CONTROL: hovering a regular kPasswordEntry row is correctly gated -- + // the cleartext password is NOT sent to the renderer. + // ------------------------------------------------------------------------- + EXPECT_CALL(*client.mock_driver(), PreviewSuggestion(_, _)).Times(0); + password_autofill_manager_->DidSelectSuggestion( + autofill::test::CreateAutofillSuggestion( + autofill::SuggestionType::kPasswordEntry, test_username_)); + testing::Mock::VerifyAndClearExpectations(client.mock_driver()); + + // ------------------------------------------------------------------------- + // (b) BUG: hovering a kBackupPasswordEntry row bypasses the gate -- the + // cleartext backup password IS sent to the renderer with no biometric + // prompt. If the bug were fixed this expectation would FAIL (Times(0)). + // ------------------------------------------------------------------------- + const Suggestion::PasswordSuggestionDetails payload( + test_username_, test_password_, backup_password_); + // EXPECTATION DOCUMENTS THE BUG: driver receives cleartext backup password + // despite IsBiometricAuthenticationBeforeFillingEnabled()==true. + EXPECT_CALL(*client.mock_driver(), + PreviewSuggestion(test_username_, backup_password_)) + .Times(1); + password_autofill_manager_->DidSelectSuggestion( + autofill::test::CreateAutofillSuggestion( + autofill::SuggestionType::kBackupPasswordEntry, test_username_, + payload)); + testing::Mock::VerifyAndClearExpectations(client.mock_driver()); +} + TEST_F(PasswordAutofillManagerTest, PasswordRecoveryFlow_ClickTroubleSigningInSuggestion) { fill_data().preferred_login.backup_password_value = kAliceBackupPassword;