Chrome · Chrome for iOS
CVE-2026-13892
Logic Error in Chrome for iOS
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifios/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
Patch
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.
References
On This Page