Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in PreviewTab
DescriptionInsufficient policy enforcement in PreviewTab
ComponentPreviewTab
Bug ClassLogic Error
Tracker385662278
Fix commit62735f629147 (chromium/src) +114/-24
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
modified

Files Changed

  • chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
  • chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
  • chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java
From 62735f62914783d07bc9f4618c725ac8d94358c9 Mon Sep 17 00:00:00 2001
From: Jinsuk Kim <jinsukkim@chromium.org>
Date: Fri, 17 Apr 2026 14:53:38 -0700
Subject: [PATCH] [PreviewTab] Fix SameSite Strict Cookie bypass

When a user selects "Preview page" from the context menu, the browser
creates a new WebContents for the ephemeral tab. This navigation was
being treated as a standard, browser-initiated navigation, which made
the network stack perceive it as a first-party request (similar to
typing a URL in the address bar), which incorrectly includes Strict
cookies even if the source site is different.

To fix this, this CL adds the initiator origin of the page where the
context menu was triggered is captured and passed into the navigation
parameters of the preview tab. EphemeralTabCoordinator#requestOpenSheet
now accepts the initiator as well to build the correct LoadUrlParams to
use for navigation.

Bug: 385662278
Change-Id: Ie841d3f14f890815df2e3b795d134bc875985a27
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7766064
Reviewed-by: Theresa Wellington <twellington@chromium.org>
Commit-Queue: Jinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1616874}
---

diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
index 3535761..80c5b1d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
@@ -109,7 +109,8 @@
                     getTitle(),
                     profile,
                     /* canPromoteToNewTab= */ true,
-                    /* shouldHaveContextMenu= */ false);
+                    /* shouldHaveContextMenu= */ false,
+                    /* initiatorOrigin= */ null);
 
             mMainController.dismiss();
         } else {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
index a914f96..33ebc0d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -407,6 +407,7 @@
         if (ephemeralTabCoordinator == null) {
             return;
         }
+        var initiatorOrigin = getWebContents().getMainFrame().getLastCommittedOrigin();
         ephemeralTabCoordinator.requestOpenSheet(
                 url,
                 /* fullPageUrl= */ null,
@@ -415,7 +416,8 @@
                 /* canPromoteToNewTab= */ mActivityType == ActivityType.TABBED
                         || mActivityType == ActivityType.CUSTOM_TAB,
                 /* shouldHaveContextMenu= */ ChromeFeatureList.isEnabled(
-                        ChromeFeatureList.ENABLE_CONTEXT_MENU_FOR_PREVIEW_TAB));
+                        ChromeFeatureList.ENABLE_CONTEXT_MENU_FOR_PREVIEW_TAB),
+                initiatorOrigin);
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java
index 95beeebe..e40df8b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/previewtab/PreviewTabTest.java
@@ -17,17 +17,22 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager;
 import org.chromium.chrome.browser.ephemeraltab.EphemeralTabCoordinator;
 import org.chromium.chrome.browser.ephemeraltab.EphemeralTabObserver;
 import org.chromium.chrome.browser.ephemeraltab.EphemeralTabSheetContent;
 import org.chromium.chrome.browser.firstrun.DisableFirstRun;
+import org.chromium.chrome.browser.flags.ActivityType;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabContextMenuItemDelegate;
 import org.chromium.chrome.browser.tabbed_mode.TabbedRootUiCoordinator;
 import org.chromium.chrome.browser.tabmodel.IncognitoTabHostUtils;
+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.R;
 import org.chromium.chrome.test.transit.ChromeTransitTestRules;
@@ -38,10 +43,15 @@
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport;
 import org.chromium.content_public.browser.NavigationHandle;
+import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.test.util.DOMUtils;
+import org.chromium.content_public.browser.test.util.JavaScriptUtils;
+import org.chromium.content_public.common.ContentSwitches;
+import org.chromium.net.test.EmbeddedTestServer;
 import org.chromium.url.GURL;
 
 import java.util.concurrent.TimeoutException;
+import java.util.function.Supplier;
 
 /**
  * Tests the Preview Tab, also known as the Ephemeral Tab. Based on the
@@ -127,6 +137,45 @@
                 mEphemeralTabCoordinator.isOpened());
     }
 
+    private void openUrlInPreviewTab(String url) throws Exception {
+        CallbackHelper callbackHelper = new CallbackHelper();
+        int callCount = callbackHelper.getCallCount();
+        ThreadUtils.runOnUiThreadBlocking(
+                () -> {
+                    ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+                    var rootUiCoordinator = cta.getRootUiCoordinatorForTesting();
+                    var tab = cta.getActivityTab();
+                    var tabModelSelector = cta.getTabModelSelectorSupplier().get();
+                    var ephemeralTabCoordinatorSupplier =
+                            rootUiCoordinator.getEphemeralTabCoordinatorSupplier();
+                    Supplier<SnackbarManager> snackbarManagerSupplier =
+                            () -> cta.getSnackbarManager();
+                    Supplier<BottomSheetController> bottomSheetControllerSupplier =
+                            () -> rootUiCoordinator.getBottomSheetController();
+                    var contextMenu =
+                            new TabContextMenuItemDelegate(
+                                    cta,
+                                    ActivityType.TABBED,
+                                    tab,
+                                    tabModelSelector,
+                                    ephemeralTabCoordinatorSupplier,
+                                    () -> {},
+                                    snackbarManagerSupplier,
+                                    bottomSheetControllerSupplier);
+                    ephemeralTabCoordinatorSupplier
+                            .get()
+                            .addObserver(
+                                    new EphemeralTabObserver() {
+                                        @Override
+                                        public void onNavigationFinished(GURL clickedUrl) {
+                                            callbackHelper.notifyCalled();
+                                        }
+                                    });
+                    contextMenu.onOpenInEphemeralTab(new GURL(url), "Echo Cookie");
+                });
+        callbackHelper.waitForCallback(callCount);
+    }
+
     /**
      * Test bringing up the PT, scrolling the base page but never expanding the PT, then closing it.
      */
@@ -217,7 +266,8 @@
                                 "PreviewTab",
                                 mActivityTestRule.getProfile(false),
                                 /* canPromoteToNewTab= */ true,
-                                /* shouldHaveContextMenu= */ true));
+                                /* shouldHaveContextMenu= */ true,
+                                /* initiatorOrigin= */ null));
         endAnimations();
         Assert.assertTrue("The Preview Tab did not open", mEphemeralTabCoordinator.isOpened());
         Assert.assertTrue("Contextual Search should be suppressed", csManager.isSuppressed());
@@ -244,7 +294,8 @@
                                 "PreviewTab",
                                 mActivityTestRule.getProfile(false),
                                 /* canPromoteToNewTab= */ true,
-                                /* shouldHaveContextMenu= */ true));
+                                /* shouldHaveContextMenu= */ true,
+                                /* initiatorOrigin= */ null));
         endAnimations();
 
         mEphemeralTabObserver.onToolbarCreatedCallback.waitForCallback(0, 1);
@@ -262,4 +313,33 @@
 
         closePreviewTab();
     }
+
+    /**
+     * Test that SameSite=Strict cookies are not sent in the preview tab when it's considered a
+     * cross-site navigation from the main tab.
+     */
+    @Test
+    @MediumTest
+    @Feature({"PreviewTab"})
+    @CommandLineFlags.Add(ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1")
+    public void testSameSiteStrictCookie() throws Throwable {
+        EmbeddedTestServer testServer = mActivityTestRule.getTestServer();
+        String cookie = "secret_token=12345";
+        String setCookieUrl =
+                testServer.getURLWithHostName(
+                        "a.com", "/set-cookie?" + cookie + ";SameSite=Strict;Path=/");
+        mActivityTestRule.loadUrlInNewTab(setCookieUrl);
+        mActivityTestRule.loadUrl(testServer.getURLWithHostName("b.com", BASE_PAGE));
+
+        // Cross-site navigation (b.com -> a.com) to preview tab
+        String echoCookieUrl = testServer.getURLWithHostName("a.com", "/echoheader?Cookie");
+        openUrlInPreviewTab(echoCookieUrl);
+
+        WebContents webContents = mEphemeralTabCoordinator.getWebContentsForTesting();
+        String content =
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(
Loading diff…

Original Bug Report

reported by ja...@gmail.com

[Android] Security: Chrome Page Preview Bypass SameSite Strict Cookies

This is a copy of https://crbug.com/385260469 to track the same problem in Chrome on Android’s Preview Page feature.


Report description

Security: Chrome Link Preview Bypass SameSite Strict Cookies


Bug location

Where do you want to report your vulnerability?

Chrome VRP – Report security issues affecting the Chrome browser. See program rules


The problem

Please describe the technical details of the vulnerability

SameSite Strict Cookies shouldn’t be sent from Cross Site requests even from Top Level Navigations, Opening new windows etc. This is bypassed in Chrome Link Previews.

YouTube POC - https://youtu.be/MKnkr_zWTIA

Steps to Reproduce -

  1. Visit https://httpbin.org/cookies/set/test/test, intercept response from Burp & modify Set-Cookie: test=test; Path=/ to Set-Cookie: test=test; SameSite=Strict; Path=/; .
  2. Now in google search, search for httpbin.org, open the link from google search, notice from Burp Suite, in httpbin.org request, test cookie isn’t sent from cross site request as expected.
  3. Now again do google search for httpbin.org, Instead of clicking on link, right click on link, then click Preview Link.
  4. Notice in Burp Suite, test cookie is sent in cross site request.

Please briefly explain who can exploit the vulnerability, and what they gain when doing so

Attacker can bypass samesite restrictions & perform GET based CSRF attacks or cause harm to users.


The cause

What version of Chrome have you found the security issue in?

Version 130.0.6723.70 (Official Build) (64-bit)

No

Choose the type of vulnerability

Site Isolation Bypass

How would you like to be publicly acknowledged for your report?

Jayateertha Guruprasad

View on issue tracker