CVE-2026-12458
Overview
Files Changed
chrome/browser/ui/views/passwords/account_chooser_dialog_view.ccchrome/browser/ui/views/passwords/account_chooser_dialog_view.hchrome/browser/ui/views/passwords/password_combined_selector_view.ccchrome/browser/ui/views/passwords/password_combined_selector_view.h
Patch
From b1f5d7fbf5101101bf1015f729535d13285be0cc Mon Sep 17 00:00:00 2001 From: Adem Derinel <[email protected]> Date: Tue, 09 Jun 2026 06:37:46 -0700 Subject: [PATCH] Disable key events during input protection in get() password dialogs Overrode ShouldAllowKeyEventsDuringInputProtection() to return false in AccountChooserDialogView and PasswordCombinedSelectorView. Fixed: 517258337 Change-Id: I67f727a5d9c898380c0887b3ac40cd08bee09f96 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7911384 Commit-Queue: Adem Derinel <[email protected]> Reviewed-by: Mohamed Amir Yosef <[email protected]> Cr-Commit-Position: refs/heads/main@{#1643913} --- diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc index 9a1ac17..ac0f3e9 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc @@ -116,6 +116,11 @@ return false; } +bool AccountChooserDialogView::ShouldAllowKeyEventsDuringInputProtection() + const { + return false; +} + void AccountChooserDialogView::InitWindow() { auto contents_view = std::make_unique<views::View>(); contents_view->SetLayoutManager(std::make_unique<views::FillLayout>()); diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h index bb8589b..8201511 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.h @@ -35,6 +35,7 @@ // DialogDelegate: bool Accept() override; + bool ShouldAllowKeyEventsDuringInputProtection() const override; private: std::u16string GetWindowTitle() const override; diff --git a/chrome/browser/ui/views/passwords/password_combined_selector_view.cc b/chrome/browser/ui/views/passwords/password_combined_selector_view.cc index 6da03ed..6181727 100644 --- a/chrome/browser/ui/views/passwords/password_combined_selector_view.cc +++ b/chrome/browser/ui/views/passwords/password_combined_selector_view.cc @@ -522,6 +522,11 @@ return false; } +bool PasswordCombinedSelectorView::ShouldAllowKeyEventsDuringInputProtection() + const { + return false; +} + void PasswordCombinedSelectorView::InitWindow() { auto main_view = std::make_unique<PasswordCombinedSelectorViewWrapper>(); main_view->SetLayoutManager(std::make_unique<views::FillLayout>()); diff --git a/chrome/browser/ui/views/passwords/password_combined_selector_view.h b/chrome/browser/ui/views/passwords/password_combined_selector_view.h index b8d360c..33cc9f4 100644 --- a/chrome/browser/ui/views/passwords/password_combined_selector_view.h +++ b/chrome/browser/ui/views/passwords/password_combined_selector_view.h @@ -49,6 +49,7 @@ // views::DialogDelegate: bool Accept() override; + bool ShouldAllowKeyEventsDuringInputProtection() const override; const std::vector<raw_ptr<views::RadioButton>>& GetRadioButtonsForTesting() const {
Original Bug Report
Keyjacking in Credential Management chooser discloses cross-origin passwords
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. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.
Overview: The Credential Management API account chooser dialogue views are potentially vulnerable to keyjacking because the default ‘Sign in’ (OK) button is focused automatically upon display and key events bypass input activation protection. An attacker-controlled PSL-matched or affiliated origin can request credentials without transient user activation, then hijack a rapid user keystroke (such as Enter or Space) to instantly accept the prompt. This potentially releases the victim’s saved cross-origin password in cleartext to the requesting page’s renderer.
Affected files:
chrome/browser/ui/views/passwords/account_chooser_dialog_view.ccchrome/browser/ui/views/passwords/password_combined_selector_view.cc
Estimated timestamp from git blame: 2026-02-10
Root Cause Analysis
The navigator.credentials.get({password:true}) account-chooser dialog (AccountChooserDialogView and its unified UI replacement PasswordCombinedSelectorView) is a security-decision UI that releases a saved password for a different origin (PSL-matched or affiliation-grouped) to the requesting page.
Two critical details make these dialog views potentially vulnerable to keyjacking:
- The OK (‘Sign in’) button is default-focused upon showing.
- Key events bypass the
InputEventActivationProtectorminimum-show-time safety gate.
Neither view overrides GetInitiallyFocusedView(). As a result, the default implementation of DialogDelegate::GetInitiallyFocusedView() is executed and focuses the default OK button initially:
// ui/views/window/dialog_delegate.cc
View* DialogDelegate::GetInitiallyFocusedView() {
...
int default_button = GetDefaultDialogButton(); // returns kOk
...
if (default_button & static_cast<int>(ui::mojom::DialogButton::kOk)) {
return dcv->ok_button(); // OK is initially focused
}
}
Furthermore, neither view overrides ShouldAllowKeyEventsDuringInputProtection(), which defaults to returning true. During dialog interaction, DialogClientView::ButtonPressed calls InputEventActivationProtector::IsPossiblyUnintendedInteraction with allow_key_events=true:
// ui/views/window/dialog_client_view.cc
void DialogClientView::ButtonPressed(ui::mojom::DialogButton type,
const ui::Event& event) {
...
if (... input_protector_->IsPossiblyUnintendedInteraction(
event, /*allow_key_events=*/delegate
->ShouldAllowKeyEventsDuringInputProtection())) {
return;
}
... delegate->AcceptDialog();
}
In InputEventActivationProtector::IsPossiblyUnintendedInteraction, non-repeat key events with allow_key_events=true immediately return false, meaning they completely bypass the minimum-show-time safety gate (view_protected_time_stamp_ is never checked against):
// ui/views/input_event_activation_protector.cc
if (event.IsKeyEvent() && event.AsKeyEvent()->is_repeat()) { return true; }
if (!event.IsMouseEvent() && !event.IsTouchEvent() && !event.IsGestureEvent()) {
if (allow_key_events || !event.IsKeyEvent()) {
return false; // non-repeat key event: NOT gated by minimum-show-time protector
}
}
This behavior allows a page sharing the same registerable domain (or affiliation group) to steal credentials via a single rapid, socially-engineered keypress.
Potential Attack Scenario
Note: These are potential steps, as our tooling agent doesn’t yet have the ability to run code or verify a full proof-of-concept.
- The user has saved credentials for
login.example.com. - The user navigates to an attacker-controlled page sharing the same eTLD+1 (e.g.,
attacker.example.com). - The attacker page calls
navigator.credentials.get({password:true, mediation:'required'})to query credentials without needing a transient user activation gate. - The browser gathers matched credentials, detects a Public Suffix List (PSL) match, and decides to display the account chooser dialog (since automated sign-in is disallowed for non-exact matches).
- The dialog is shown and takes active keyboard focus, defaulting its focus directly onto the ‘Sign in’ (OK) button.
- The attacker page presents a call-to-action (e.g., asking the user to “Press Enter to continue”). When the user presses Enter, the key event is targeted directly at the focused ‘Sign in’ button of the dialog.
- The keypress completely bypasses the activation protector’s short delay gate and immediately triggers acceptance of the dialog, sending the cleartext credential back to the renderer process.
Suggested Remediation
To align the account chooser dialog views with other security-sensitive dialogs in Chromium (such as PasswordCrossDomainConfirmationPopupViewViews):
- Avoid default-focusing the OK/Sign-in button. Override
GetInitiallyFocusedView()inAccountChooserDialogViewandPasswordCombinedSelectorViewto focus the Cancel/Close button instead. - Override
ShouldAllowKeyEventsDuringInputProtection()to returnfalseso that key events are subject to the same minimum-show-time safety gate as mouse and touch events.
Evaluated with Chrome root at commit: b1520ef4a76878853a31f0943b565e42060edec8
Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:
- If you are familiar with the severity guidelines, you may adjust the severity.
- If this is a false positive, and there’s no work to be done, please close as WAI.
- If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.
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.