Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in TabSwitcher
DescriptionInsufficient validation of untrusted input in TabSwitcher
ComponentTabSwitcher
Bug ClassLogic Error
Tracker512997517
Fix commit7c2f4d21d5a8 (chromium/src) +47/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
for
chrome/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.java
  • chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/LocalTabGroupMutationHelperUnitTest.java
From 7c2f4d21d5a88d8e9e6c624aa3a33d897391502a Mon Sep 17 00:00:00 2001
From: Calder Kitagawa <[email protected]>
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 <[email protected]>
Auto-Submit: Calder Kitagawa <[email protected]>
Commit-Queue: Sky Malice <[email protected]>
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.