Chrome · Browser
CVE-2026-79041
Logic Error in Browser
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
BookmarkMenuBridgechrome/browser/app_controller_mac.h |
modified | |
forchrome/browser/app_controller_mac.mm |
modified |
Files Changed
chrome/browser/BUILD.gnchrome/browser/app_controller_mac.hchrome/browser/app_controller_mac.mm
Patch
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.
References
On This Page