Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUI misrepresentation in Passwords
DescriptionUI misrepresentation in Passwords
ComponentPasswords
Bug ClassLogic Error
Tracker533116484
Fix commit49e2dbf4709a (chromium/src) +63/-16
CISA KEVNot listed
CreditedGoogle
Disclosed2026-09-08

Changed Functions

FunctionChangeNotes
TEST_F
chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
modified
GURL
chrome/browser/webauthn/touch_to_fill_credential_receiver.h
modified

Files Changed

  • chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.cc
  • chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.h
  • chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_delegate.h
  • chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.cc
  • chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.h
  • chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
  • chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
  • chrome/browser/webauthn/android/webauthn_request_delegate_android.h
  • chrome/browser/webauthn/touch_to_fill_credential_receiver.h
From 49e2dbf4709abf6b1de30e5a27bcdac76e872bec Mon Sep 17 00:00:00 2001
From: Friedrich Horschig <[email protected]>
Date: Tue, 28 Jul 2026 06:46:55 -0700
Subject: [PATCH] [Android][WebAuthn] Fix frame origin retrieval in TTF Delegate

Prior to this CL, the origin of the parent frame would always be used
when the "No Passkeys bottom sheet" shows up for a request originating
from a subframe.

This CL fixes the display issue and the const correctness of the getter.

Fixed: 533116484
Change-Id: Ib1ecba0e949754d487637c30e8aae0a430212c02
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8163621
Reviewed-by: Adem Derinel <[email protected]>
Commit-Queue: Friedrich Hauser <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1669428}
---

diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.cc b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.cc
index 1e874b6..7cc957d4 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.cc
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.cc
@@ -228,12 +228,13 @@
   std::move(action_completed).Run();
 }
 
-GURL TouchToFillPasswordManagerCredentialDelegate::GetFrameUrl() {
+GURL TouchToFillPasswordManagerCredentialDelegate::GetFrameUrl() const {
   CHECK(filler_);
   return filler_->GetFrameUrl();
 }
 
-url::Origin TouchToFillPasswordManagerCredentialDelegate::GetFrameOrigin() {
+url::Origin TouchToFillPasswordManagerCredentialDelegate::GetFrameOrigin()
+    const {
   CHECK(filler_);
   return filler_->GetFrameOrigin();
 }
diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.h b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.h
index c820880..245a2af3 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.h
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_credential_delegate.h
@@ -126,8 +126,8 @@
   void OnHybridSignInSelected(base::OnceClosure action_completed) override;
   void OnDismiss(base::OnceClosure action_completed) override;
   void OnCredManDismissed(base::OnceClosure action_completed) override;
-  GURL GetFrameUrl() override;
-  url::Origin GetFrameOrigin() override;
+  GURL GetFrameUrl() const override;
+  url::Origin GetFrameOrigin() const override;
   bool ShouldShowTouchToFill() override;
   bool ShouldTriggerSubmission() override;
   bool ShouldShowHybridOption() override;
diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_delegate.h b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_delegate.h
index 7aff6db..11fd5cc 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_delegate.h
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_delegate.h
@@ -64,11 +64,11 @@
 
   // Gets the last committed URL for the frame that triggered this sheet to be
   // created.
-  virtual GURL GetFrameUrl() = 0;
+  virtual GURL GetFrameUrl() const = 0;
 
   // Gets the last committed origin for the frame that triggered this sheet to
   // be created.
-  virtual url::Origin GetFrameOrigin() = 0;
+  virtual url::Origin GetFrameOrigin() const = 0;
 
   // Returns whether TTF is eligible for showing for the currently focused field
   // (e. g. it should not be triggered for the new password field).
diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.cc b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.cc
index b40b068..ab61e7a 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.cc
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.cc
@@ -82,16 +82,13 @@
   std::move(action_completed).Run();
 }
 
-GURL TouchToFillPasswordManagerWebAuthnDelegate::GetFrameUrl() {
-  return credential_receiver_->web_contents()->GetLastCommittedURL();
+GURL TouchToFillPasswordManagerWebAuthnDelegate::GetFrameUrl() const {
+  return credential_receiver_ ? credential_receiver_->GetFrameUrl() : GURL();
 }
 
-url::Origin TouchToFillPasswordManagerWebAuthnDelegate::GetFrameOrigin() {
-  return credential_receiver_->web_contents()
-             ? credential_receiver_->web_contents()
-                   ->GetPrimaryMainFrame()
-                   ->GetLastCommittedOrigin()
-             : url::Origin();
+url::Origin TouchToFillPasswordManagerWebAuthnDelegate::GetFrameOrigin() const {
+  return credential_receiver_ ? credential_receiver_->GetFrameOrigin()
+                              : url::Origin();
 }
 
 bool TouchToFillPasswordManagerWebAuthnDelegate::ShouldShowTouchToFill() {
diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.h b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.h
index 56b3cf1..39aada9 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.h
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate.h
@@ -68,8 +68,8 @@
   void OnHybridSignInSelected(base::OnceClosure action_completed) override;
   void OnDismiss(base::OnceClosure action_completed) override;
   void OnCredManDismissed(base::OnceClosure action_completed) override;
-  GURL GetFrameUrl() override;
-  url::Origin GetFrameOrigin() override;
+  GURL GetFrameUrl() const override;
+  url::Origin GetFrameOrigin() const override;
   bool ShouldShowTouchToFill() override;
   bool ShouldTriggerSubmission() override;
   bool ShouldShowHybridOption() override;
diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
index 02d1027..172a8cd 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
@@ -100,6 +100,14 @@
   MOCK_METHOD(void, OnHybridSignInSelected, (), (override));
 
   content::WebContents* web_contents() override { return web_contents_; }
+  GURL GetFrameUrl() const override {
+    return web_contents_ ? web_contents_->GetLastCommittedURL() : GURL();
+  }
+  url::Origin GetFrameOrigin() const override {
+    return web_contents_
+               ? web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin()
+               : url::Origin();
+  }
 
  private:
   raw_ptr<content::WebContents> web_contents_;
@@ -373,3 +381,25 @@
                    std::vector<TouchToFillPasswordManagerView::Credential>,
                    bool)>(webauthn::sorting::SortTouchToFillCredentials)));
 }
+
+TEST_F(TouchToFillPasswordManagerWebAuthnDelegateTest, GetFrameUrlAndOrigin) {
+  auto delegate = MakeTouchToFillPasswordManagerControllerDelegate(
+      /*should_show_hybrid_option=*/false,
+      /*is_immediate=*/true,
+      /*sorting_callback=*/base::NullCallback());
+
+  EXPECT_EQ(delegate->GetFrameUrl(), GURL(kExampleCom));
+  EXPECT_EQ(delegate->GetFrameOrigin(), url::Origin::Create(GURL(kExampleCom)));
+}
+
+TEST_F(TouchToFillPasswordManagerWebAuthnDelegateTest,
+       GetFrameUrlAndOriginNullReceiver) {
+  TouchToFillPasswordManagerWebAuthnDelegate delegate(
+      /*receiver=*/nullptr,
+      /*sort_credentials_callback=*/base::NullCallback(),
+      /*should_show_hybrid_option=*/false,
+      /*is_immediate=*/true);
+
+  EXPECT_EQ(delegate.GetFrameUrl(), GURL());
+  EXPECT_TRUE(delegate.GetFrameOrigin().opaque());
+}
diff --git a/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc b/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
index cde7019e..c9ee628b 100644
--- a/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
+++ b/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
@@ -251,3 +251,11 @@
 content::WebContents* WebAuthnRequestDelegateAndroid::web_contents() {
   return content::WebContents::FromRenderFrameHost(&render_frame_host());
 }
+
+GURL WebAuthnRequestDelegateAndroid::GetFrameUrl() const {
+  return render_frame_host().GetLastCommittedURL();
+}
+
+url::Origin WebAuthnRequestDelegateAndroid::GetFrameOrigin() const {
+  return render_frame_host().GetLastCommittedOrigin();
+}
diff --git a/chrome/browser/webauthn/android/webauthn_request_delegate_android.h b/chrome/browser/webauthn/android/webauthn_request_delegate_android.h
index 0b067c6..ee9392d 100644
--- a/chrome/browser/webauthn/android/webauthn_request_delegate_android.h
+++ b/chrome/browser/webauthn/android/webauthn_request_delegate_android.h
@@ -80,6 +80,8 @@
   void OnCredentialSelectionDeclined() override;
   void OnHybridSignInSelected() override;
   content::WebContents* web_contents() override;
+  GURL GetFrameUrl() const override;
+  url::Origin GetFrameOrigin() const override;
 
   // Returns a delegate associated with the |frame_host|. It creates one if
   // one does not already exist.
diff --git a/chrome/browser/webauthn/touch_to_fill_credential_receiver.h b/chrome/browser/webauthn/touch_to_fill_credential_receiver.h
index c963c31..4da9f8d1b 100644
--- a/chrome/browser/webauthn/touch_to_fill_credential_receiver.h
+++ b/chrome/browser/webauthn/touch_to_fill_credential_receiver.h
@@ -9,6 +9,9 @@
 #include <vector>
 
 #include "chrome/browser/webauthn/shared_types.h"
+#include "url/origin.h"
+
+class GURL;
 
 namespace content {
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
index 02d1027..172a8cd 100644
--- a/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
+++ b/chrome/browser/touch_to_fill/password_manager/touch_to_fill_password_manager_webauthn_delegate_unittest.cc
@@ -100,6 +100,14 @@
   MOCK_METHOD(void, OnHybridSignInSelected, (), (override));
 
   content::WebContents* web_contents() override { return web_contents_; }
+  GURL GetFrameUrl() const override {
+    return web_contents_ ? web_contents_->GetLastCommittedURL() : GURL();
+  }
+  url::Origin GetFrameOrigin() const override {
+    return web_contents_
+               ? web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin()
+               : url::Origin();
+  }
 
  private:
   raw_ptr<content::WebContents> web_contents_;
@@ -373,3 +381,25 @@
                    std::vector<TouchToFillPasswordManagerView::Credential>,
                    bool)>(webauthn::sorting::SortTouchToFillCredentials)));
 }
+
+TEST_F(TouchToFillPasswordManagerWebAuthnDelegateTest, GetFrameUrlAndOrigin) {
+  auto delegate = MakeTouchToFillPasswordManagerControllerDelegate(
+      /*should_show_hybrid_option=*/false,
+      /*is_immediate=*/true,
+      /*sorting_callback=*/base::NullCallback());
+
+  EXPECT_EQ(delegate->GetFrameUrl(), GURL(kExampleCom));
+  EXPECT_EQ(delegate->GetFrameOrigin(), url::Origin::Create(GURL(kExampleCom)));
+}
+
+TEST_F(TouchToFillPasswordManagerWebAuthnDelegateTest,
+       GetFrameUrlAndOriginNullReceiver) {
+  TouchToFillPasswordManagerWebAuthnDelegate delegate(
+      /*receiver=*/nullptr,
+      /*sort_credentials_callback=*/base::NullCallback(),
+      /*should_show_hybrid_option=*/false,
+      /*is_immediate=*/true);
+
+  EXPECT_EQ(delegate.GetFrameUrl(), GURL());
+  EXPECT_TRUE(delegate.GetFrameOrigin().opaque());
+}
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.