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 <[email protected]> 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 <[email protected]> > > Reviewed-by: Avi Drissman <[email protected]> > > 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 <[email protected]> > Reviewed-by: Andrea Gomez <[email protected]> > Bot-Commit: [email protected] <[email protected]> > Owners-Override: Andrea Gomez <[email protected]> > Commit-Queue: Andrea Gomez <[email protected]> > 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: [email protected] <[email protected]> Commit-Queue: Deepak Ravichandran <[email protected]> Reviewed-by: Andrea Gomez <[email protected]> Owners-Override: Andrea Gomez <[email protected]> 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