Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactMissing authorization in Browser
DescriptionMissing authorization in Browser
ComponentBrowser
Bug ClassLogic Error
Tracker518249083
Fix commit831a446cd4cc (chromium/src) +133/-115
CISA KEVNot listed
CreditedGoogle
Disclosed2026-08-25

Changed Functions

FunctionChangeNotes
BookmarkMenuBridge
chrome/browser/app_controller_mac.h
modified
for
chrome/browser/app_controller_mac.mm
modified

Files Changed

  • chrome/browser/BUILD.gn
  • chrome/browser/app_controller_mac.h
  • chrome/browser/app_controller_mac.mm
From 831a446cd4ccd3f2738e0f622093d7f7eed7b4f7 Mon Sep 17 00:00:00 2001
From: Deepak Ravichandran <deepakr@google.com>
Date: Thu, 30 Jul 2026 04:39:12 -0700
Subject: [PATCH] Reland "[macOS] Preserve untrusted launch status for direct launch URLs"

This reverts commit bfd17025198217b42c660ee15ca8383dc69eea66.

Reason for revert:  I am not sure if the original revert was done on the correct CL. The error messages do not make sense.


Original change's description:
> Revert "[macOS] Preserve untrusted launch status for direct launch URLs"
>
> This reverts commit e964c0794fca66bff95a3e78973b32d9e1adf4d0.
>
> Reason for revert: Build failure on Linux
>
> Failure Link: https://ci.chromium.org/ui/p/chromium/builders/ci/linux-arm64-dbg/8808/overview
>
> Original change's description:
> > [macOS] Preserve untrusted launch status for direct launch URLs
> >
> > On macOS, external URLs using the google-chrome:// (or chromium://)
> > scheme are processed in AppController application:openURLs:. Previously,
> > stripped URLs were stored as standard GURLs in std::vector<GURL>,
> > dropping the provenance that they originated from an external launch.
> >
> > As a result, when StartupBrowserCreatorImpl opened these URLs into tabs,
> > is_untrusted_launch defaulted to false. This left
> > params.initiator_origin as nullopt, causing ExtensionNavigationThrottle
> > to treat the navigation as a trusted internal request and bypassing Web
> > Accessible Resources (WAR) checks for extension pages.
> >
> > This CL fixes the issue by:
> >
> > 1. Updating AppController to maintain and propagate StartupTabs instead
> > of std::vector<GURL>, explicitly marking direct launch URLs with
> > is_untrusted_launch = true.
> >
> > 2. Preserving StartupTabs (and their untrusted launch status) when
> > queuing urls before startup is complete.
> >
> > 3. Passing StartupTabs through OpenStartupTabsInBrowserWithProfile so
> > StartupBrowserCreatorImpl sets an opaque initiator_origin on launch.
> >
> > 4. Enabling and adding browser test coverage in
> > app_controller_mac_google_chrome_scheme_browsertest.mm to verify an
> > opaque initiator origin is assigned.
> >
> > Bug: 518249083,446672134
> > Change-Id: Ib9d319d8c58fb3c5fcd45850aa6d9591f524b1e6
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8101603
> > Commit-Queue: Deepak Ravichandran <deepakr@google.com>
> > Reviewed-by: Avi Drissman <avi@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#1670621}
>
> Bug: 518249083,446672134
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Change-Id: I026f2f2b1fb58ecb2aea2ede390a7151aa91687d
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8169720
> Auto-Submit: Andrea Gomez <andreaxg@google.com>
> Reviewed-by: Andrea Gomez <andreaxg@google.com>
> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> Owners-Override: Andrea Gomez <andreaxg@google.com>
> Commit-Queue: Andrea Gomez <andreaxg@google.com>
> Cr-Commit-Position: refs/heads/main@{#1670627}

Bug: 518249083,446672134
Change-Id: Iabe22218cc306f5a1d7014a0821da03b763b7164
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8166529
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Deepak Ravichandran <deepakr@google.com>
Reviewed-by: Andrea Gomez <andreaxg@google.com>
Owners-Override: Andrea Gomez <andreaxg@google.com>
Cr-Commit-Position: refs/heads/main@{#1670975}
---

diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 1a9c0bd..1fb021f0 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -568,6 +568,7 @@
       "//base",
       "//chrome/browser/profiles",
       "//chrome/browser/profiles/keep_alive",
+      "//chrome/browser/ui/startup:startup_tab",
       "//components/prefs",
       "//components/sessions",
     ]
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index 64d79d71..801fbd1 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -22,6 +22,7 @@
 
 #include "base/files/file_path.h"
 #include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
+#include "chrome/browser/ui/startup/startup_tab.h"
 #include "components/prefs/pref_change_registrar.h"
 
 class BookmarkMenuBridge;
@@ -131,8 +132,6 @@
 // Delegate method to return the dock menu.
 - (NSMenu*)applicationDockMenu:(NSApplication*)sender;
 
-// Get the URLs that Launch Services expects the browser to open at startup.
-- (const std::vector<GURL>&)startupUrls;
 
 - (BookmarkMenuBridge*)bookmarkMenuBridge;
 - (HistoryMenuBridge*)historyMenuBridge;
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index c0e3326..9c306fbd 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -165,10 +165,6 @@
   return g_pending_requests;
 }
 
-// Open the urls in the last used browser from a regular profile.
-void OpenUrlsInBrowserWithProfile(const std::vector<GURL>& urls,
-                                  Profile* profile);
-
 // Returns true if the profile requires signin before being used.
 bool IsProfileSignedOut(const base::FilePath& profile_path);
 
@@ -433,19 +429,20 @@
   return profile_path_info.path;
 }
 
-// Open the urls in the last used browser. Loads the profile asynchronously if
-// needed.
-void OpenUrlsInBrowser(std::vector<GURL> urls) {
-  std::vector<GURL> regular_urls;
+void OpenStartupTabsInBrowserWithProfile(const StartupTabs& tabs,
+                                         Profile* profile);
+
+void OpenStartupTabsInBrowser(StartupTabs tabs) {
+  StartupTabs regular_tabs;
   std::vector<base::FilePath> shortcuts;
 
-  for (auto& url : urls) {
+  for (auto& tab : tabs) {
     base::FilePath path;
-    if (net::FileURLToFilePath(url, &path) &&
+    if (net::FileURLToFilePath(tab.url, &path) &&
         path.Extension() == shortcuts::ChromeWeblocFile::kFileExtension) {
       shortcuts.push_back(path);
     } else {
-      regular_urls.push_back(std::move(url));
+      regular_tabs.push_back(std::move(tab));
     }
   }
 
@@ -458,7 +455,7 @@
          base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
         base::BindOnce(
             [](const std::vector<base::FilePath>& shortcuts) {
-              base::flat_map<base::FilePath, std::vector<GURL>> profile_url_map;
+              base::flat_map<base::FilePath, StartupTabs> profile_tab_map;
               for (const auto& path : shortcuts) {
                 auto shortcut = shortcuts::ChromeWeblocFile::LoadFromFile(path);
                 // TODO: Consider opening the original file URL?
@@ -467,8 +464,6 @@
                 }
                 bool is_shortcut_url_valid =
                     startup::ValidateLaunchUrlWebUnsafe(shortcut->target_url());
-        // Do not allow chrome sensitive urls to be launched from a .crwebloc
-        // file.
 #if BUILDFLAG(ENABLE_EXTENSIONS)
                 is_shortcut_url_valid =
                     is_shortcut_url_valid || shortcut->target_url().SchemeIs(
@@ -479,45 +474,44 @@
                              << shortcut->target_url();
                   continue;
                 }
-                profile_url_map[shortcut->profile_path_name().path()].push_back(
-                    shortcut->target_url());
+                profile_tab_map[shortcut->profile_path_name().path()]
+                    .emplace_back(shortcut->target_url(),
+                                  /*is_untrusted_launch=*/false);
               }
-              return profile_url_map;
+              return profile_tab_map;
             },
             std::move(shortcuts)),
-        base::BindOnce(
-            [](const base::flat_map<base::FilePath, std::vector<GURL>>
-                   profile_url_map) {
-              const base::FilePath& user_data_dir =
-                  g_browser_process->profile_manager()->user_data_dir();
-              ProfileAttributesStorage& profile_attributes_storage =
-                  g_browser_process->profile_manager()
-                      ->GetProfileAttributesStorage();
-              for (const auto& [profile, urls_for_profile] : profile_url_map) {
-                const base::FilePath profile_path =
-                    user_data_dir.Append(profile);
-                if (profile_attributes_storage.GetProfileAttributesWithPath(
-                        profile_path)) {
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/app_controller_mac_google_chrome_scheme_browsertest.mm b/chrome/browser/app_controller_mac_google_chrome_scheme_browsertest.mm
index a5927720..458a919d 100644
--- a/chrome/browser/app_controller_mac_google_chrome_scheme_browsertest.mm
+++ b/chrome/browser/app_controller_mac_google_chrome_scheme_browsertest.mm
@@ -12,6 +12,9 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "net/base/apple/url_conversions.h"
 
@@ -31,9 +34,8 @@
 
 using AppControllerGoogleChromeSchemeBrowserTest = InProcessBrowserTest;
 
-// TODO(crbuig.com/446672134): Fix and re-enable.
 IN_PROC_BROWSER_TEST_F(AppControllerGoogleChromeSchemeBrowserTest,
-                       DISABLED_OpenSchemeUrl) {
+                       OpenSchemeUrl) {
   std::string scheme = shell_integration::GetDirectLaunchUrlScheme();
   if (scheme.empty()) {
     // Scheme not supported for this channel (e.g. Beta/Dev/Canary).
@@ -55,6 +57,31 @@
 }
 
 IN_PROC_BROWSER_TEST_F(AppControllerGoogleChromeSchemeBrowserTest,
+                       OpenSchemeUrlSetsOpaqueInitiator) {
+  std::string scheme = shell_integration::GetDirectLaunchUrlScheme();
+  if (scheme.empty()) {
+    // Scheme not supported for this channel (e.g. Beta/Dev/Canary).
+    return;
+  }
+
+  GURL target_url("http://example.com/");
+  std::string scheme_url_str = scheme + "://" + target_url.spec();
+  NSURL* scheme_url =
+      [NSURL URLWithString:base::SysUTF8ToNSString(scheme_url_str)];
+
+  ui_test_utils::AllBrowserTabAddedWaiter waiter;
+
+  AppController* app_controller = AppController.sharedController;
+  [app_controller application:NSApp openURLs:@[ scheme_url ]];
+
+  content::WebContents* new_tab = waiter.Wait();
+  EXPECT_EQ(new_tab->GetVisibleURL(), target_url);
+
+  EXPECT_TRUE(
+      new_tab->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque());
+}
+
+IN_PROC_BROWSER_TEST_F(AppControllerGoogleChromeSchemeBrowserTest,
                        OpenSchemeUrlInvalid) {
   std::string scheme = shell_integration::GetDirectLaunchUrlScheme();
   if (scheme.empty()) {
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.