Low CVSS 6.5 chrome Policy Bypass 🔧 Commit mapped

Overview

Low
Severity
6.5
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in Passwords
DescriptionInsufficient policy enforcement in Passwords
ComponentPasswords
Bug ClassPolicy Bypass
Tracker501708647
Fix commit08456f50839d (chromium/src) +41/-3
CWECWE-693
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
CISA KEVNot listed
CreditedGoogle
Reported2026-04-11 (per vendor advisory)
Fix landed2026-05-19 (public git)
Disclosed2026-06-30
Patch gap42 days — fix public in source before the advisory

Changed Functions

FunctionChangeNotes
if
components/password_manager/core/browser/undo_password_change_controller.cc
modified

Files Changed

  • components/password_manager/core/browser/undo_password_change_controller.cc
  • components/password_manager/core/browser/undo_password_change_controller_unittest.cc
From 08456f50839dffaefdf84205548fe537eb434870 Mon Sep 17 00:00:00 2001
From: Oleksandr Tara <otara@google.com>
Date: Tue, 19 May 2026 01:50:09 -0700
Subject: [PATCH] Ignore grouped affiliations for proactive password recovery.

Suggestions from grouped affiliations need to show cross-domain
confirmation before filling but to achieve this in the proactive
password recovery, we need non-trivial amount of work. Instead, as a
quick fix, we can disable proactive recovery for passwords from grouped
affiliations.

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

diff --git a/components/password_manager/core/browser/undo_password_change_controller.cc b/components/password_manager/core/browser/undo_password_change_controller.cc
index d18f18c0..3239365 100644
--- a/components/password_manager/core/browser/undo_password_change_controller.cc
+++ b/components/password_manager/core/browser/undo_password_change_controller.cc
@@ -30,6 +30,29 @@
 constexpr char kPasswordChangeRecoveryFlowStateHistogram[] =
     "PasswordManager.PasswordChangeRecoveryFlow";
 
+bool IsFormEligibleForProactiveRecovery(
+    const StoredCredential* form_best_match,
+    const std::u16string& failed_password_value) {
+  if (!form_best_match) {
+    return false;
+  }
+
+  if (password_manager_util::GetMatchType(*form_best_match) ==
+      password_manager_util::GetLoginMatchType::kGrouped) {
+    return false;
+  }
+
+  if (!form_best_match->GetPasswordBackup()) {
+    return false;
+  }
+
+  if (form_best_match->GetPasswordBackup() == failed_password_value) {
+    return false;
+  }
+
+  return true;
+}
+
 }  // namespace
 
 UndoPasswordChangeController::UndoPasswordChangeController() = default;
@@ -168,9 +191,8 @@
     const StoredCredential* form_best_match =
         password_manager_util::FindCredentialByUsername(
             form_manager->GetBestMatches(), failed_login_form_->username_value);
-    if (!form_best_match || !form_best_match->GetPasswordBackup() ||
-        form_best_match->GetPasswordBackup() ==
-            failed_login_form_->password_value) {
+    if (!IsFormEligibleForProactiveRecovery(
+            form_best_match, failed_login_form_->password_value)) {
       FinishObserving();
       return;
     }
diff --git a/components/password_manager/core/browser/undo_password_change_controller_unittest.cc b/components/password_manager/core/browser/undo_password_change_controller_unittest.cc
index cb3498d3..5b72771e 100644
--- a/components/password_manager/core/browser/undo_password_change_controller_unittest.cc
+++ b/components/password_manager/core/browser/undo_password_change_controller_unittest.cc
@@ -383,6 +383,22 @@
 }
 
 TEST_F(UndoPasswordChangeControllerTest,
+       OnLoginPotentiallyFailed_GroupedAffiliation_Ignored) {
+  best_match_form_.SetPasswordBackupNote(kBackupPassword);
+  best_match_form_.match_type =
+      password_manager::PasswordForm::MatchType::kGrouped;
+  auto form_manager = CreateFormManager(best_match_form_);
+
+  controller_.OnLoginPotentiallyFailed(&driver_, failed_login_form_);
+  EXPECT_CALL(driver_, TriggerPasswordRecoverySuggestions).Times(0);
+  static_cast<PasswordFormManagerObserver*>(&controller_)
+      ->OnPasswordFormParsed(form_manager.get());
+
+  EXPECT_EQ(controller_.GetState(kUsername),
+            PasswordRecoveryState::kRegularFlow);
+}
+
+TEST_F(UndoPasswordChangeControllerTest,
        FindLoginWithProactiveRecoveryStateNoMatch) {
   best_match_form_.SetPasswordBackupNote(kBackupPassword);
   auto form_manager = CreateFormManager(best_match_form_);
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/components/password_manager/core/browser/undo_password_change_controller_unittest.cc b/components/password_manager/core/browser/undo_password_change_controller_unittest.cc
index cb3498d3..5b72771e 100644
--- a/components/password_manager/core/browser/undo_password_change_controller_unittest.cc
+++ b/components/password_manager/core/browser/undo_password_change_controller_unittest.cc
@@ -383,6 +383,22 @@
 }
 
 TEST_F(UndoPasswordChangeControllerTest,
+       OnLoginPotentiallyFailed_GroupedAffiliation_Ignored) {
+  best_match_form_.SetPasswordBackupNote(kBackupPassword);
+  best_match_form_.match_type =
+      password_manager::PasswordForm::MatchType::kGrouped;
+  auto form_manager = CreateFormManager(best_match_form_);
+
+  controller_.OnLoginPotentiallyFailed(&driver_, failed_login_form_);
+  EXPECT_CALL(driver_, TriggerPasswordRecoverySuggestions).Times(0);
+  static_cast<PasswordFormManagerObserver*>(&controller_)
+      ->OnPasswordFormParsed(form_manager.get());
+
+  EXPECT_EQ(controller_.GetState(kUsername),
+            PasswordRecoveryState::kRegularFlow);
+}
+
+TEST_F(UndoPasswordChangeControllerTest,
        FindLoginWithProactiveRecoveryStateNoMatch) {
   best_match_form_.SetPasswordBackupNote(kBackupPassword);
   auto form_manager = CreateFormManager(best_match_form_);
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.