Chrome · TabSwitcher
CVE-2026-14080
Logic Error in TabSwitcher
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
forchrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java |
modified |
Files Changed
chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.javachrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
Patch
From 7c2f4d21d5a88d8e9e6c624aa3a33d897391502a Mon Sep 17 00:00:00 2001
From: Calder Kitagawa <ckitagawa@chromium.org>
Date: Thu, 14 May 2026 07:40:04 -0700
Subject: [PATCH] More URL validation in LocalTabGroupMutationHelper
Bug: 512997517
Change-Id: Ib6bf82bad2654f89439638c611a29562dcd7acf0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7849399
Reviewed-by: Sky Malice <skym@chromium.org>
Auto-Submit: Calder Kitagawa <ckitagawa@chromium.org>
Commit-Queue: Sky Malice <skym@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1630614}
---
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java
index 8f1c59c..e87d3d0 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelper.java
@@ -75,9 +75,14 @@
List<Tab> tabs = new ArrayList<>();
for (SavedTabGroupTab savedTab : tabGroup.savedTabs) {
String title = savedTab.title == null ? UNSET_TAB_GROUP_TITLE : savedTab.title;
+ GURL url = assertNonNull(savedTab.url);
+ if (!TabGroupSyncUtils.isSavableUrl(url)) {
+ title = TabGroupSyncUtils.UNSAVEABLE_TAB_TITLE;
+ url = TabGroupSyncUtils.UNSAVEABLE_URL_OVERRIDE;
+ }
Tab newTab =
mTabCreationDelegate.createBackgroundTab(
- assertNonNull(savedTab.url), title, /* parent= */ null, position++);
+ url, title, /* parent= */ null, position++);
assert newTab != null;
tabs.add(newTab);
tabIdMappings.put(assertNonNull(savedTab.syncId), newTab.getId());
@@ -220,6 +225,10 @@
/** Helper method to create a tab with a given URL and add it to the tab group. */
private Tab createTabAndAddToGroup(
GURL url, String title, int desiredTabModelIndex, Tab parentTab, Token tabGroupId) {
+ if (!TabGroupSyncUtils.isSavableUrl(url)) {
+ title = TabGroupSyncUtils.UNSAVEABLE_TAB_TITLE;
+ url = TabGroupSyncUtils.UNSAVEABLE_URL_OVERRIDE;
+ }
Tab newTab =
mTabCreationDelegate.createBackgroundTab(
url, title, parentTab, desiredTabModelIndex);
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
index cc0dbd6..c781777 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
@@ -172,6 +172,22 @@
}
@Test
+ public void testCreateNewTabGroup_UnsavableUrl() {
+ SavedTabGroup savedTabGroup = createOneSavedTabGroup(null, new Integer[] {null});
+ SavedTabGroupTab savedTab = savedTabGroup.savedTabs.get(0);
+ savedTab.url = UNSYNCABLE_URL_1;
+
+ mLocalMutationHelper.createNewTabGroup(savedTabGroup, OpeningSource.AUTO_OPENED_FROM_SYNC);
+
+ verify(mTabCreationDelegate)
+ .createBackgroundTab(
+ eq(TabGroupSyncUtils.UNSAVEABLE_URL_OVERRIDE),
+ eq(TabGroupSyncUtils.UNSAVEABLE_TAB_TITLE),
+ any(),
+ anyInt());
+ }
+
+ @Test
public void testUpdateTabGroupUpdatesVisuals() {
addOneTab();
SavedTabGroup savedTabGroup =
@@ -227,6 +243,27 @@
}
@Test
+ public void testUpdateTabGroup_AddTabFromSync_UnsavableUrl() {
+ // One local group with one tab syncing.
+ addOneTab();
+
+ // One saved group with two tabs: one mapped, one new with unsavable URL.
+ SavedTabGroup savedTabGroup =
+ createOneSavedTabGroup(LOCAL_TAB_GROUP_ID_1, new Integer[] {TAB_ID_1, null});
+ SavedTabGroupTab savedTab = savedTabGroup.savedTabs.get(1);
+ savedTab.url = UNSYNCABLE_URL_1;
+
+ mLocalMutationHelper.updateTabGroup(savedTabGroup);
+
+ verify(mTabCreationDelegate)
+ .createBackgroundTab(
+ eq(TabGroupSyncUtils.UNSAVEABLE_URL_OVERRIDE),
+ eq(TabGroupSyncUtils.UNSAVEABLE_TAB_TITLE),
+ any(),
+ anyInt());
+ }
+
+ @Test
public void testUpdateTabGroup_UpdateExistingTab_Navigate() {
// One local group with one tab syncing.
addOneTab();
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