Medium chrome Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInappropriate implementation in Chrome for iOS
DescriptionInappropriate implementation in Chrome for iOS
ComponentChrome for iOS
Bug ClassLogic Error
Tracker501674841
Fix commit2233714ad379 (chromium/src) +25/-14
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
if
ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_injection_handler.mm
modified

Files Changed

  • ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_injection_handler.mm
From 2233714ad379ab3cd1487e5f4b513139a4484d25 Mon Sep 17 00:00:00 2001
From: Alexis Hétu <[email protected]>
Date: Tue, 12 May 2026 16:14:33 -0700
Subject: [PATCH] [iOS] Pinned Target Web Frame During Asynchronous Field Injection

Pass the targeted frame ID explicitly to manual fill injection helper
methods. This ensures the target frame is pinned when the user selects
a suggestion, preventing race conditions or incorrect frame targeting
during asynchronous flows like reauthentication.

Bug: 501674841
Change-Id: I3472287814f882221312a1139ccc557ead156953
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7843312
Reviewed-by: Tommy Martino <[email protected]>
Commit-Queue: Alexis Hétu <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1629616}
---

diff --git a/ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_injection_handler.mm b/ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_injection_handler.mm
index 3017ecc..e4b14d4 100644
--- a/ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_injection_handler.mm
+++ b/ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_injection_handler.mm
@@ -161,8 +161,11 @@
 
   if ([self canUserInjectInPasswordField:passwordField
                            requiresHTTPS:requiresHTTPS]) {
+    // Store the current frame ID to make sure it isn't modified during the
+    // reauthentication process.
+    const std::string frameID = self.lastFocusedElementFrameIdentifier;
     if (!passwordField) {
-      [self fillLastSelectedFieldWithString:content];
+      [self fillLastSelectedFieldWithString:content frameId:frameID];
       return;
     }
 
@@ -173,7 +176,7 @@
         if (result != ReauthenticationResult::kFailure) {
           UmaHistogramEnumeration("IOS.Reauth.Password.ManualFallback",
                                   ReauthenticationEvent::kSuccess);
-          [weakSelf fillLastSelectedFieldWithString:content];
+          [weakSelf fillLastSelectedFieldWithString:content frameId:frameID];
         } else {
           UmaHistogramEnumeration("IOS.Reauth.Password.ManualFallback",
                                   ReauthenticationEvent::kFailure);
@@ -187,7 +190,7 @@
     } else {
       UmaHistogramEnumeration("IOS.Reauth.Password.ManualFallback",
                               ReauthenticationEvent::kMissingPasscode);
-      [self fillLastSelectedFieldWithString:content];
+      [self fillLastSelectedFieldWithString:content frameId:frameID];
     }
   }
 }
@@ -263,9 +266,12 @@
     return url::Origin();
   }
   web::WebState* activeWebState = _webStateList->GetActiveWebState();
-  web::WebFrame* frame = activeWebState
-                             ? [self activeWebFrameFromWebState:activeWebState]
-                             : nullptr;
+  if (!activeWebState) {
+    return url::Origin();
+  }
+  web::WebFrame* frame =
+      [self activeWebFrameFromWebState:activeWebState
+                               frameId:self.lastFocusedElementFrameIdentifier];
   return frame ? frame->GetSecurityOrigin() : url::Origin();
 }
 
@@ -292,17 +298,18 @@
 
 #pragma mark - Private
 
-// Returns the last focused web frame associated with the given `webState`.
-- (web::WebFrame*)activeWebFrameFromWebState:(web::WebState*)webState {
+// Returns the web frame with `frameId` associated with the given `webState`.
+- (web::WebFrame*)activeWebFrameFromWebState:(web::WebState*)webState
+                                     frameId:(const std::string&)frameId {
   autofill::AutofillJavaScriptFeature* feature =
       autofill::AutofillJavaScriptFeature::GetInstance();
 
-  return feature->GetWebFramesManager(webState)->GetFrameWithId(
-      self.lastFocusedElementFrameIdentifier);
+  return feature->GetWebFramesManager(webState)->GetFrameWithId(frameId);
 }
 
 // Injects the passed string to the active field and jumps to the next field.
-- (void)fillLastSelectedFieldWithString:(NSString*)string {
+- (void)fillLastSelectedFieldWithString:(NSString*)string
+                                frameId:(const std::string&)frameId {
   if (!_webStateList) {
     return;
   }
@@ -312,7 +319,7 @@
   }
 
   web::WebFrame* activeWebFrame =
-      [self activeWebFrameFromWebState:activeWebState];
+      [self activeWebFrameFromWebState:activeWebState frameId:frameId];
   if (!activeWebFrame) {
     return;
   }
@@ -383,7 +390,9 @@
       tabHelper->GetPasswordManager();
   CHECK(passwordManager);
 
-  web::WebFrame* frame = [self activeWebFrameFromWebState:webState];
+  web::WebFrame* frame =
+      [self activeWebFrameFromWebState:webState
+                               frameId:self.lastFocusedElementFrameIdentifier];
   if (!frame) {
     return nil;
   }
@@ -415,7 +424,9 @@
 - (void)fillFormWithFillData:(FillData)fillData
                     webState:(web::WebState*)webState
                   formHelper:(PasswordFormHelper*)formHelper {
-  web::WebFrame* activeWebFrame = [self activeWebFrameFromWebState:webState];
+  web::WebFrame* activeWebFrame =
+      [self activeWebFrameFromWebState:webState
+                               frameId:self.lastFocusedElementFrameIdentifier];
   if (!activeWebFrame) {
     return;
   }
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.