Medium chrome Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in iOS
DescriptionInsufficient validation of untrusted input in iOS
ComponentChromium
Bug ClassLogic Error
Tracker474338157
Fix commit4b80a20a9e14 (chromium/src) +14/-59
CISA KEVNot listed
CreditedQadhafy Muhammad Tera
Disclosed2026-05-05

Changed Functions

FunctionChangeNotes
if
ios/chrome/browser/download/coordinator/download_manager_mediator.mm
modified
if
ios/chrome/browser/download/ui/download_manager_view_controller.mm
modified

Files Changed

  • ios/chrome/browser/download/coordinator/download_manager_mediator.h
  • ios/chrome/browser/download/coordinator/download_manager_mediator.mm
  • ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
  • ios/chrome/browser/download/ui/download_manager_consumer.h
  • ios/chrome/browser/download/ui/download_manager_view_controller.mm
  • ios/chrome/test/fakes/fake_download_manager_consumer.h
From 4b80a20a9e149f08efe8437ca00f3e87c113ade8 Mon Sep 17 00:00:00 2001
From: Quentin Pubert <[email protected]>
Date: Wed, 18 Mar 2026 05:41:17 -0700
Subject: [PATCH] [iOS] Always show origin in download manager

This CL changes the download mediator UI so that the download origin
will no longer be hidden if it happens to match the content of the
address bar. Instead there will either be a origin host displayed if any
is available, or instead a string indicating that the origin of the
download is unknown.

Bug: 474338157
Change-Id: Iae9389ac3aed54b5afefc72079d277b79daeeb1a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7674638
Reviewed-by: Olivier Robin <[email protected]>
Auto-Submit: Quentin Pubert <[email protected]>
Reviewed-by: Ewann Pellé <[email protected]>
Commit-Queue: Olivier Robin <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1601200}
---

diff --git a/ios/chrome/browser/download/coordinator/download_manager_mediator.h b/ios/chrome/browser/download/coordinator/download_manager_mediator.h
index 6b8c8769..95c6771b 100644
--- a/ios/chrome/browser/download/coordinator/download_manager_mediator.h
+++ b/ios/chrome/browser/download/coordinator/download_manager_mediator.h
@@ -148,7 +148,6 @@
   // Observers for NSNotificationCenter notifications.
   __strong id<NSObject> application_foregrounding_observer_;
   bool is_google_drive_app_installed_ = false;
-  bool should_show_origin_ = false;
 
   base::WeakPtrFactory<DownloadManagerMediator> weak_ptr_factory_;
 };
diff --git a/ios/chrome/browser/download/coordinator/download_manager_mediator.mm b/ios/chrome/browser/download/coordinator/download_manager_mediator.mm
index e6d04fb5..1f074fb 100644
--- a/ios/chrome/browser/download/coordinator/download_manager_mediator.mm
+++ b/ios/chrome/browser/download/coordinator/download_manager_mediator.mm
@@ -246,7 +246,6 @@
   [consumer_ setFileName:base::apple::FilePathToNSString(filename)];
 
   NSString* originating_host = nil;
-  bool display_originating_host = false;
   if (@available(iOS 18.2, *)) {
     // The originating host is only populated when compiled with iOS18.2 SDK
     // and running on iOS18.2.
@@ -259,19 +258,9 @@
       originating_host =
           base::SysUTF8ToNSString(download_task_->GetRedirectedUrl().GetHost());
     }
-    // Only show the compute the originating host if it is not what is displayed
-    // in the omnibox.
-    display_originating_host =
-        download_task_->GetWebState()->GetLastCommittedURL().GetHost() !=
-        base::SysNSStringToUTF8(originating_host);
-
-    // If the host was already displayed, keep it displayed
-    display_originating_host = display_originating_host || should_show_origin_;
-    should_show_origin_ = display_originating_host;
   }
 
-  [consumer_ setOriginatingHost:originating_host
-                        display:display_originating_host];
+  [consumer_ setOriginatingHost:originating_host];
 
   int a11y_announcement = GetDownloadManagerA11yAnnouncement();
   if (a11y_announcement != -1) {
diff --git a/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm b/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
index b1159d7..c0273a1 100644
--- a/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
+++ b/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
@@ -351,21 +351,18 @@
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kSameDomainURL).GetHost()));
-  EXPECT_FALSE(consumer_.originatingHostDisplayed);
 
   // WebState and task have different domains.
   web_state_->SetCurrentURL(GURL(kCrossDomainURL));
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kSameDomainURL).GetHost()));
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
 
   // Navigate back, origin should still be visible.
   web_state_->SetCurrentURL(GURL(kSameDomainURL));
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kSameDomainURL).GetHost()));
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
 
   // Reset Mediator.
   web_state_->SetCurrentURL(GURL(kSameDomainURL));
@@ -380,19 +377,4 @@
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kCrossDomainURL).GetHost()));
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
-
-  // Reset Mediator.
-  web_state_->SetCurrentURL(GURL(kSameDomainURL));
-  mediator = std::make_unique<DownloadManagerMediator>();
-  mediator->SetDownloadTask(task());
-  mediator->SetConsumer(consumer_);
-
-  // Check that if no URL is available, the placeholder is displayed.
-  task()->SetRedirectedURL(GURL("data:"));
-  task()->SetOriginatingHost(@"");
-  web_state_->SetCurrentURL(GURL("data:"));
-  mediator->UpdateConsumer();
-  EXPECT_NSEQ(consumer_.originatingHost, nil);
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
 }
diff --git a/ios/chrome/browser/download/ui/download_manager_consumer.h b/ios/chrome/browser/download/ui/download_manager_consumer.h
index fb5d489..8359d13e 100644
--- a/ios/chrome/browser/download/ui/download_manager_consumer.h
+++ b/ios/chrome/browser/download/ui/download_manager_consumer.h
@@ -41,11 +41,9 @@
 // Sets visible state to Install Google Drive button.
 - (void)setInstallDriveButtonVisible:(BOOL)visible animated:(BOOL)animated;
 
-// Sets the originating host for the consumer.
-// If `display` is false, then the string is not displayed to the user.
-// If `display` is true, the host is displayed in the details of the download,
-// with a special string if the host is actually empty.
-- (void)setOriginatingHost:(NSString*)originatingHost display:(BOOL)display;
+// Sets the originating host for the consumer. If `originatingHost` is nil then
+// it means that the source of the download is unknown.
+- (void)setOriginatingHost:(NSString*)originatingHost;
 
 @optional
 
diff --git a/ios/chrome/browser/download/ui/download_manager_view_controller.mm b/ios/chrome/browser/download/ui/download_manager_view_controller.mm
index 86a9969..6af12ef 100644
--- a/ios/chrome/browser/download/ui/download_manager_view_controller.mm
+++ b/ios/chrome/browser/download/ui/download_manager_view_controller.mm
@@ -147,7 +147,6 @@
 @interface DownloadManagerViewController () <FullscreenUIElement> {
   NSString* _fileName;
   NSString* _originatingHost;
-  BOOL _displayOriginatingHost;
   int64_t _countOfBytesReceived;
   int64_t _countOfBytesExpectedToReceive;
   float _progress;
@@ -352,13 +351,12 @@
   }
 }
 
-- (void)setOriginatingHost:(NSString*)originatingHost display:(BOOL)display {
-  if ([_originatingHost isEqualToString:originatingHost] &&
-      _displayOriginatingHost == display) {
+- (void)setOriginatingHost:(NSString*)originatingHost {
+  if (_originatingHost == originatingHost ||
+      [_originatingHost isEqualToString:originatingHost]) {
     return;
   }
   _originatingHost = [originatingHost copy];
-  _displayOriginatingHost = display;
   [self updateViews];
 }
 
@@ -817,16 +815,13 @@
   self.statusLabel.text = [self localizedFileNameAndSizeWithPeriod:NO];
   // Update detail label text.
   NSMutableArray* details = [NSMutableArray array];
-  if (_displayOriginatingHost) {
-    if ([_originatingHost length]) {
-      [details addObject:l10n_util::GetNSStringF(
-                             IDS_IOS_DOWNLOAD_MANAGER_ORIGIN_HOST_LABEL,
-                             base::SysNSStringToUTF16(_originatingHost))];
-    } else {
-      [details
-          addObject:l10n_util::GetNSString(
-                        IDS_IOS_DOWNLOAD_MANAGER_ORIGIN_HOST_UNKNOWN_LABEL)];
-    }
+  if ([_originatingHost length]) {
+    [details addObject:l10n_util::GetNSStringF(
+                           IDS_IOS_DOWNLOAD_MANAGER_ORIGIN_HOST_LABEL,
+                           base::SysNSStringToUTF16(_originatingHost))];
+  } else {
+    [details addObject:l10n_util::GetNSString(
+                           IDS_IOS_DOWNLOAD_MANAGER_ORIGIN_HOST_UNKNOWN_LABEL)];
   }
   if (self.incognito) {
     [details addObject:l10n_util::GetNSString(
diff --git a/ios/chrome/test/fakes/fake_download_manager_consumer.h b/ios/chrome/test/fakes/fake_download_manager_consumer.h
index f4b00442..32752eb6 100644
--- a/ios/chrome/test/fakes/fake_download_manager_consumer.h
+++ b/ios/chrome/test/fakes/fake_download_manager_consumer.h
@@ -34,9 +34,6 @@
 // The host that triggered the download.
 @property(nonatomic) NSString* originatingHost;
 
-// Whether the originating host is displayed.
-@property(nonatomic) BOOL originatingHostDisplayed;
-
 @end
 
 #endif  // IOS_CHROME_TEST_FAKES_FAKE_DOWNLOAD_MANAGER_CONSUMER_H_
diff --git a/ios/chrome/test/fakes/fake_download_manager_consumer.mm b/ios/chrome/test/fakes/fake_download_manager_consumer.mm
index cf5d544..6d46d66 100644
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm b/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
index b1159d7..c0273a1 100644
--- a/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
+++ b/ios/chrome/browser/download/coordinator/download_manager_mediator_unittest.mm
@@ -351,21 +351,18 @@
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kSameDomainURL).GetHost()));
-  EXPECT_FALSE(consumer_.originatingHostDisplayed);
 
   // WebState and task have different domains.
   web_state_->SetCurrentURL(GURL(kCrossDomainURL));
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kSameDomainURL).GetHost()));
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
 
   // Navigate back, origin should still be visible.
   web_state_->SetCurrentURL(GURL(kSameDomainURL));
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kSameDomainURL).GetHost()));
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
 
   // Reset Mediator.
   web_state_->SetCurrentURL(GURL(kSameDomainURL));
@@ -380,19 +377,4 @@
   mediator->UpdateConsumer();
   EXPECT_NSEQ(consumer_.originatingHost,
               base::SysUTF8ToNSString(GURL(kCrossDomainURL).GetHost()));
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
-
-  // Reset Mediator.
-  web_state_->SetCurrentURL(GURL(kSameDomainURL));
-  mediator = std::make_unique<DownloadManagerMediator>();
-  mediator->SetDownloadTask(task());
-  mediator->SetConsumer(consumer_);
-
-  // Check that if no URL is available, the placeholder is displayed.
-  task()->SetRedirectedURL(GURL("data:"));
-  task()->SetOriginatingHost(@"");
-  web_state_->SetCurrentURL(GURL("data:"));
-  mediator->UpdateConsumer();
-  EXPECT_NSEQ(consumer_.originatingHost, nil);
-  EXPECT_TRUE(consumer_.originatingHostDisplayed);
 }
diff --git a/ios/chrome/test/fakes/fake_download_manager_consumer.h b/ios/chrome/test/fakes/fake_download_manager_consumer.h
index f4b00442..32752eb6 100644
--- a/ios/chrome/test/fakes/fake_download_manager_consumer.h
+++ b/ios/chrome/test/fakes/fake_download_manager_consumer.h
@@ -34,9 +34,6 @@
 // The host that triggered the download.
 @property(nonatomic) NSString* originatingHost;
 
-// Whether the originating host is displayed.
-@property(nonatomic) BOOL originatingHostDisplayed;
-
 @end
 
 #endif  // IOS_CHROME_TEST_FAKES_FAKE_DOWNLOAD_MANAGER_CONSUMER_H_
diff --git a/ios/chrome/test/fakes/fake_download_manager_consumer.mm b/ios/chrome/test/fakes/fake_download_manager_consumer.mm
index cf5d544..6d46d66 100644
--- a/ios/chrome/test/fakes/fake_download_manager_consumer.mm
+++ b/ios/chrome/test/fakes/fake_download_manager_consumer.mm
@@ -28,9 +28,4 @@
 - (void)setCanOpenFile:(BOOL)canOpenFile {
 }
 
-- (void)setOriginatingHost:(NSString*)originatingHost display:(BOOL)display {
-  _originatingHost = originatingHost;
-  _originatingHostDisplayed = display;
-}
-
 @end
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.