Chrome · Extensions
CVE-2026-79017
Race in Extensions
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ExtensionApiPdfTestchrome/browser/extensions/api/tabs/tabs_test.cc |
modified |
Files Changed
chrome/browser/extensions/api/tabs/tabs_api.ccchrome/browser/extensions/api/tabs/tabs_test.cc
Patch
From b500751eac4a405ec8c988c29db0c2c7edd714a7 Mon Sep 17 00:00:00 2001 From: Devlin Cronin <[email protected]> Date: Wed, 15 Jul 2026 11:43:37 -0700 Subject: [PATCH] [Extensions] Use GetLastCommittedURL() in tabs zoom functions Changing the zoom settings for a tab affects the zoom settings for the frame's origin, which uses the committed origin. However, the check compared visible URL to see if it was a restricted URL. This would allow an extension to zoom a tab on a restricted URL if the visible URL differed (such as if a user navigation was under way). Fix this so that the tabs zoom checks use the last committed URL, and add a regression test. Fixed: 533021205 Change-Id: I0dfbf22eec7ae1e08c0619f00c8dac9862bf3f92 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8087626 Commit-Queue: Devlin Cronin <[email protected]> Reviewed-by: Andrea Orru <[email protected]> Auto-Submit: Devlin Cronin <[email protected]> Cr-Commit-Position: refs/heads/main@{#1662763} --- diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 3e365131..efc8a9e 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -3938,7 +3938,7 @@ return RespondNow(Error(std::move(error))); } - GURL url(web_contents->GetVisibleURL()); + const GURL& url = web_contents->GetLastCommittedURL(); if (extension()->permissions_data()->IsRestrictedUrl(url, &error)) { return RespondNow(Error(std::move(error))); } @@ -4000,7 +4000,7 @@ return RespondNow(Error(std::move(error))); } - GURL url(web_contents->GetVisibleURL()); + const GURL& url = web_contents->GetLastCommittedURL(); if (extension()->permissions_data()->IsRestrictedUrl(url, &error)) { return RespondNow(Error(std::move(error))); } diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index d3bc73d..991a9617 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc @@ -3178,9 +3178,8 @@ error = RunSetZoomSettingsExpectError(bogus_id, "manual", "per-tab"); EXPECT_TRUE(base::MatchPattern(error, ExtensionTabUtil::kTabNotFoundError)); - const char kNewTestTabArgs[] = "chrome://version"; - params = GetOpenParams(kNewTestTabArgs); - web_contents = browser()->OpenURL(params, /*navigation_handle_callback=*/{}); + const char kNewTestTabArgs[] = "chrome://version/"; + web_contents = OpenUrlAndWaitForLoad(GURL(kNewTestTabArgs)); tab_id = ExtensionTabUtil::GetTabId(web_contents); // Test chrome.tabs.setZoom(). @@ -3194,6 +3193,44 @@ base::MatchPattern(error, manifest_errors::kCannotAccessChromeUrl)); } +// Tests that tabs.zoom properly looks at the committed (not visible) URLs. +// Regression test for crbug.com/533021205. +IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest, + ZoomingRestrictedURLsChecksCommittedURL) { + ASSERT_TRUE(embedded_test_server()->Start()); + + // Open a restricted URL and wait for it to load. + const char kRestrictedUrl[] = "chrome://version/"; + content::WebContents* web_contents = + OpenUrlAndWaitForLoad(GURL(kRestrictedUrl)); + int tab_id = ExtensionTabUtil::GetTabId(web_contents); + + ASSERT_EQ(GURL(kRestrictedUrl), web_contents->GetLastCommittedURL()); + ASSERT_EQ(GURL(kRestrictedUrl), web_contents->GetVisibleURL()); + + // Start a browser-initiated navigation to an unrestricted URL, but do not + // wait for it to commit. + GURL unrestricted_url = embedded_test_server()->GetURL("/title1.html"); + content::NavigationController::LoadURLParams load_params(unrestricted_url); + web_contents->GetController().LoadURLWithParams(load_params); + + // The visible URL should update immediately to the pending navigation target. + ASSERT_EQ(unrestricted_url, web_contents->GetVisibleURL()); + // The committed URL should still be the restricted one. + ASSERT_EQ(GURL(kRestrictedUrl), web_contents->GetLastCommittedURL()); + + // Attempt to set zoom. It should fail because the committed URL is + // restricted. + std::string error = RunSetZoomExpectError(tab_id, 3.14159); + EXPECT_TRUE( + base::MatchPattern(error, manifest_errors::kCannotAccessChromeUrl)); + + // Attempt to set zoom settings. It should also fail. + error = RunSetZoomSettingsExpectError(tab_id, "manual", "per-tab"); + EXPECT_TRUE( + base::MatchPattern(error, manifest_errors::kCannotAccessChromeUrl)); +} + #if BUILDFLAG(ENABLE_PDF) class ExtensionApiPdfTest : public base::test::WithFeatureOverride, public PDFExtensionTestBase {
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc
index d3bc73d..991a9617 100644
--- a/chrome/browser/extensions/api/tabs/tabs_test.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -3178,9 +3178,8 @@
error = RunSetZoomSettingsExpectError(bogus_id, "manual", "per-tab");
EXPECT_TRUE(base::MatchPattern(error, ExtensionTabUtil::kTabNotFoundError));
- const char kNewTestTabArgs[] = "chrome://version";
- params = GetOpenParams(kNewTestTabArgs);
- web_contents = browser()->OpenURL(params, /*navigation_handle_callback=*/{});
+ const char kNewTestTabArgs[] = "chrome://version/";
+ web_contents = OpenUrlAndWaitForLoad(GURL(kNewTestTabArgs));
tab_id = ExtensionTabUtil::GetTabId(web_contents);
// Test chrome.tabs.setZoom().
@@ -3194,6 +3193,44 @@
base::MatchPattern(error, manifest_errors::kCannotAccessChromeUrl));
}
+// Tests that tabs.zoom properly looks at the committed (not visible) URLs.
+// Regression test for crbug.com/533021205.
+IN_PROC_BROWSER_TEST_F(ExtensionTabsZoomTest,
+ ZoomingRestrictedURLsChecksCommittedURL) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ // Open a restricted URL and wait for it to load.
+ const char kRestrictedUrl[] = "chrome://version/";
+ content::WebContents* web_contents =
+ OpenUrlAndWaitForLoad(GURL(kRestrictedUrl));
+ int tab_id = ExtensionTabUtil::GetTabId(web_contents);
+
+ ASSERT_EQ(GURL(kRestrictedUrl), web_contents->GetLastCommittedURL());
+ ASSERT_EQ(GURL(kRestrictedUrl), web_contents->GetVisibleURL());
+
+ // Start a browser-initiated navigation to an unrestricted URL, but do not
+ // wait for it to commit.
+ GURL unrestricted_url = embedded_test_server()->GetURL("/title1.html");
+ content::NavigationController::LoadURLParams load_params(unrestricted_url);
+ web_contents->GetController().LoadURLWithParams(load_params);
+
+ // The visible URL should update immediately to the pending navigation target.
+ ASSERT_EQ(unrestricted_url, web_contents->GetVisibleURL());
+ // The committed URL should still be the restricted one.
+ ASSERT_EQ(GURL(kRestrictedUrl), web_contents->GetLastCommittedURL());
+
+ // Attempt to set zoom. It should fail because the committed URL is
+ // restricted.
+ std::string error = RunSetZoomExpectError(tab_id, 3.14159);
+ EXPECT_TRUE(
+ base::MatchPattern(error, manifest_errors::kCannotAccessChromeUrl));
+
+ // Attempt to set zoom settings. It should also fail.
+ error = RunSetZoomSettingsExpectError(tab_id, "manual", "per-tab");
+ EXPECT_TRUE(
+ base::MatchPattern(error, manifest_errors::kCannotAccessChromeUrl));
+}
+
#if BUILDFLAG(ENABLE_PDF)
class ExtensionApiPdfTest : public base::test::WithFeatureOverride,
public PDFExtensionTestBase {
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