Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in Passwords
DescriptionInsufficient policy enforcement in Passwords
ComponentPasswords
Bug ClassLogic Error
Tracker506391032
Fix commit42d144056c10 (chromium/src) +23/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Files Changed

  • components/password_manager/core/browser/password_autofill_manager.cc
  • components/password_manager/core/browser/password_autofill_manager_unittest.cc
From 42d144056c108596c91fdbd36bf75b04f9caf9ba Mon Sep 17 00:00:00 2001
From: Oleksandr Tara <otara@google.com>
Date: Tue, 28 Apr 2026 04:44:58 -0700
Subject: [PATCH] Prevent previewing backup passwords when biometric auth before filling is enabled.

When the "Auth before filling" feature is active, selecting a backup
password suggestion should not trigger a preview. The user will be
prompted for authentication upon filling, not upon previewing.

Fixed: b:506391032
Change-Id: I0956c70e6918df846672319e119cb7573636c3d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7795698
Auto-Submit: Oleksandr Tara <otara@google.com>
Reviewed-by: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: Ioana Treib <ioanap@chromium.org>
Commit-Queue: Oleksandr Tara <otara@google.com>
Cr-Commit-Position: refs/heads/main@{#1621673}
---

diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc
index ebc746d2..d49ef30 100644
--- a/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -267,6 +267,10 @@
         suggestion
             .GetPayload<autofill::Suggestion::PasswordSuggestionDetails>();
     CHECK(payload.backup_password);
+    if (password_client_->GetPasswordFeatureManager()
+            ->IsBiometricAuthenticationBeforeFillingEnabled()) {
+      return;
+    }
     password_manager_driver_->PreviewSuggestion(
         payload.username, payload.backup_password.value());
     return;
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 a56fbc1..145ffce 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,25 @@
             PasswordRecoveryState::kRegularFlow);
 }
 
+TEST_F(
+    PasswordAutofillManagerTest,
+    PasswordRecoveryFlow_AuthBeforeFillingEnabled_NoPreviewBackupSuggestion) {
+  TestPasswordManagerClient client;
+  ON_CALL(*client.GetPasswordFeatureManager(),
+          IsBiometricAuthenticationBeforeFillingEnabled)
+      .WillByDefault(Return(true));
+
+  InitializePasswordAutofillManager(&client, nullptr);
+  const Suggestion::PasswordSuggestionDetails payload(
+      test_username_, test_password_, backup_password_);
+  const Suggestion suggestion = autofill::test::CreateAutofillSuggestion(
+      autofill::SuggestionType::kBackupPasswordEntry, test_username_, payload);
+
+  EXPECT_CALL(*client.mock_driver(), PreviewSuggestion).Times(0);
+  password_autofill_manager_->DidSelectSuggestion(suggestion);
+  testing::Mock::VerifyAndClearExpectations(client.mock_driver());
+}
+
 TEST_F(PasswordAutofillManagerTest,
        PasswordRecoveryFlow_ClickTroubleSigningInSuggestion) {
   fill_data().preferred_login.backup_password_value = kAliceBackupPassword;
Loading diff…

Regression Test / PoC

shipped with the fix
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 a56fbc1..145ffce 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,25 @@
             PasswordRecoveryState::kRegularFlow);
 }
 
+TEST_F(
+    PasswordAutofillManagerTest,
+    PasswordRecoveryFlow_AuthBeforeFillingEnabled_NoPreviewBackupSuggestion) {
+  TestPasswordManagerClient client;
+  ON_CALL(*client.GetPasswordFeatureManager(),
+          IsBiometricAuthenticationBeforeFillingEnabled)
+      .WillByDefault(Return(true));
+
+  InitializePasswordAutofillManager(&client, nullptr);
+  const Suggestion::PasswordSuggestionDetails payload(
+      test_username_, test_password_, backup_password_);
+  const Suggestion suggestion = autofill::test::CreateAutofillSuggestion(
+      autofill::SuggestionType::kBackupPasswordEntry, test_username_, payload);
+
+  EXPECT_CALL(*client.mock_driver(), PreviewSuggestion).Times(0);
+  password_autofill_manager_->DidSelectSuggestion(suggestion);
+  testing::Mock::VerifyAndClearExpectations(client.mock_driver());
+}
+
 TEST_F(PasswordAutofillManagerTest,
        PasswordRecoveryFlow_ClickTroubleSigningInSuggestion) {
   fill_data().preferred_login.backup_password_value = kAliceBackupPassword;
Loading diff…

Original Bug Report

reported by vm...@google.com

Potential biometric authentication bypass when previewing backup password suggestions

Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the Chrome Security team. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A logic flaw in PasswordAutofillManager::DidSelectSuggestion bypasses the biometric authentication gate when handling password recovery suggestions (kBackupPasswordEntry). This allows a compromised renderer process to force the browser to send a user’s cleartext backup password via a Mojo IPC without prompting the user for authentication.

Affected files:

  • components/password_manager/core/browser/password_autofill_manager.cc

Estimated timestamp from git blame: 2025-07-03

Description

When the “Use your screen lock when filling passwords” (Biometric authentication before filling) feature is enabled, Chrome is intended to withhold password values from the renderer process until the user successfully completes authentication.

However, a logic error exists in PasswordAutofillManager::DidSelectSuggestion() where suggestions of type kBackupPasswordEntry (used for the password recovery/undo flow) bypass this biometric authentication gate. When such a suggestion is selected (e.g., via a mouse hover), the cleartext backup password is sent directly to the renderer process.

Root Cause Analysis

In components/password_manager/core/browser/password_autofill_manager.cc, the DidSelectSuggestion method handles different suggestion types. For regular password suggestions, it defers to a helper method PreviewSuggestion(username, type) which correctly enforces the biometric gate:

// components/password_manager/core/browser/password_autofill_manager.cc
bool PasswordAutofillManager::PreviewSuggestion(const std::u16string& username,
                                                autofill::SuggestionType type) {
  // ...
  if (password_client_->GetPasswordFeatureManager()
          ->IsBiometricAuthenticationBeforeFillingEnabled()) {
    return false; // Biometric gate correctly blocks preview
  }
  // ... retrieves password and calls driver_->PreviewSuggestion ...
}

However, for kBackupPasswordEntry, DidSelectSuggestion explicitly bypasses this helper and directly sends the cleartext backup password to the driver:

// components/password_manager/core/browser/password_autofill_manager.cc
void PasswordAutofillManager::DidSelectSuggestion(const Suggestion& suggestion) {
  ClearPreviewedForm();
  // ...
  if (suggestion.type == autofill::SuggestionType::kBackupPasswordEntry) {
    const auto payload =
        suggestion.GetPayload<autofill::Suggestion::PasswordSuggestionDetails>();
    CHECK(payload.backup_password);
    // VULNERABILITY: Biometric gate is bypassed here.
    password_manager_driver_->PreviewSuggestion(
        payload.username, payload.backup_password.value()); 
    return;
  }
  // Normal path correctly calls the helper
  PreviewSuggestion(GetUsernameFromSuggestion(suggestion.main_text.value),
                    suggestion.type);
}

This results in the browser sending the autofill.mojom.AutofillAgent.PreviewPasswordSuggestion IPC containing the cleartext password to the renderer.

Potential Exploitation Steps

Note: These are suggested steps based on code analysis; a full working exploit has not been built to confirm this exact sequence.

  1. An attacker compromises a renderer process for a specific origin (e.g., https://example.com) and achieves Remote Code Execution (RCE).
  2. The attacker targets a user who has saved a credential for this origin that includes a backup_password_value (e.g., from a recent password change) and has enabled biometric authentication for filling.
  3. The compromised renderer constructs a fake login form and simulates a failed login by sending the autofill.mojom.PasswordManagerDriver.PasswordFormCleared IPC to the browser.
  4. The browser process (PasswordManager::OnPasswordFormCleared) detects this and activates the UndoPasswordChangeController to monitor for a page reload.
  5. The renderer simulates a reload by sending PasswordFormsParsed with the same form data.
  6. UndoPasswordChangeController recognizes the form, enters kShowProactiveRecovery state, and generates an autofill suggestion of type kBackupPasswordEntry containing the cleartext backup password in its payload.
  7. The renderer requests autofill suggestions (AskForValuesToFill IPC). The attacker controls the caret_bounds parameter to force the Autofill popup to spawn exactly underneath the user’s current, stationary mouse cursor.
  8. The OS immediately generates a hover event over the suggestion, triggering AutofillPopupControllerImpl::SelectSuggestion(0).
  9. This cascades to the vulnerable PasswordAutofillManager::DidSelectSuggestion, which bypasses the biometric check and sends the cleartext backup password to the renderer via the PreviewPasswordSuggestion IPC.
  10. The compromised renderer intercepts the IPC and steals the credential without the user ever seeing an authentication prompt.

Suggested Fix

Modify PasswordAutofillManager::DidSelectSuggestion to respect the biometric authentication setting for kBackupPasswordEntry. This could involve modifying the PreviewSuggestion helper to handle backup passwords, or adding an explicit check before calling password_manager_driver_->PreviewSuggestion:

  if (suggestion.type == autofill::SuggestionType::kBackupPasswordEntry) {
    if (password_client_->GetPasswordFeatureManager()
            ->IsBiometricAuthenticationBeforeFillingEnabled()) {
      return;
    }
    // ... proceed with preview ...

Evaluated with Chrome root at commit: a1e33f5848218e21d4a16ae2c1bc94e815c30c7f


Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker