Medium chrome Logic Error 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient policy enforcement in Payments
DescriptionInsufficient policy enforcement in Payments
ComponentPayments
Bug ClassLogic Error
Tracker470646792
Fix commit4d76210c7828 (chromium/src) +82/-7
CISA KEVNot listed
CreditedJorian Woltjer
Disclosed2026-05-12

Changed Functions

FunctionChangeNotes
if
chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
modified

Files Changed

  • chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
  • chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java
From 4d76210c7828d2d67024ea1b3b0ba9ec7206d2a5 Mon Sep 17 00:00:00 2001
From: Jayden Nikifork <nikifork@google.com>
Date: Tue, 14 Jul 2026 06:48:20 -0700
Subject: [PATCH] [bug][payment] Add initiator for clank payment handler dialog

Add the merchant site as the initiator for the payment handler modal
dialog popup. This fixes the SameSite cookie bypass security
vulnerability.

Note that this bug has already been fixed for desktop:
https://crrev.com/e158cad632facb1c5348ad9ca1a40216cdd1aa2a.

Bug: 470646792
Change-Id: I0321d25b40172aa851f1549d258c300485c9db88
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8071878
Reviewed-by: Darwin Yang <darwinyang@chromium.org>
Commit-Queue: Jayden Nikifork <nikifork@google.com>
Reviewed-by: Xuehui Chen <xuehuichen@google.com>
Cr-Commit-Position: refs/heads/main@{#1661811}
---

diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
index 7c025b0..4680580d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/PaymentHandlerCoordinator.java
@@ -23,6 +23,7 @@
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
 import org.chromium.components.embedder_support.view.ContentView;
+import org.chromium.components.payments.PaymentFeatureList;
 import org.chromium.components.payments.PaymentHandlerNavigationThrottle;
 import org.chromium.components.payments.ui.InputProtector;
 import org.chromium.components.thinwebview.ThinWebView;
@@ -33,6 +34,7 @@
 import org.chromium.content_public.browser.SelectionClient;
 import org.chromium.content_public.browser.SelectionPopupController;
 import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.browser.WebContentsObserver;
 import org.chromium.ui.base.IntentRequestTracker;
 import org.chromium.ui.base.ViewAndroidDelegate;
 import org.chromium.ui.base.WindowAndroid;
@@ -40,6 +42,7 @@
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 import org.chromium.url.GURL;
+import org.chromium.url.Origin;
 
 /**
  * PaymentHandler coordinator, which owns the component overall, i.e., creates other objects in the
@@ -52,6 +55,7 @@
     private @Nullable Runnable mHider;
     private @Nullable WebContents mPaymentHandlerWebContents;
     private @Nullable PaymentHandlerToolbarCoordinator mToolbarCoordinator;
+    private @Nullable WebContentsObserver mWebContentsObserverForTest;
     private InputProtector mInputProtector = new InputProtector();
 
     /** Constructs the payment-handler component coordinator. */
@@ -66,6 +70,10 @@
         void onPaymentHandlerUiShown();
     }
 
+    public void setWebContentsObserverForTest(WebContentsObserver observer) {
+        mWebContentsObserverForTest = observer;
+    }
+
     /**
      * Shows the payment-handler UI.
      *
@@ -90,10 +98,13 @@
         mInputProtector.markShowTime();
         mPaymentHandlerWebContents =
                 WebContentsFactory.createWebContents(profile, /* initiallyHidden= */ false, false);
+        if (mWebContentsObserverForTest != null) {
+            mWebContentsObserverForTest.observe(mPaymentHandlerWebContents);
+        }
         PaymentHandlerNavigationThrottle.markPaymentHandlerWebContents(mPaymentHandlerWebContents);
         ContentView webContentView =
                 ContentView.createContentView(activity, mPaymentHandlerWebContents);
-        initializeWebContents(windowAndroid, webContentView, url);
+        initializeWebContents(windowAndroid, webContentView, paymentRequestWebContents, url);
 
         mToolbarCoordinator =
                 new PaymentHandlerToolbarCoordinator(
@@ -186,7 +197,10 @@
 
     @RequiresNonNull("mPaymentHandlerWebContents")
     private void initializeWebContents(
-            WindowAndroid windowAndroid, ContentView webContentView, GURL url) {
+            WindowAndroid windowAndroid,
+            ContentView webContentView,
+            WebContents paymentRequestWebContents,
+            GURL url) {
         mPaymentHandlerWebContents.setDelegates(
                 VersionInfo.getProductVersion(),
                 ViewAndroidDelegate.createBasicDelegate(webContentView),
@@ -201,9 +215,13 @@
         controller.setSelectionClient(
                 SelectionClient.createSmartSelectionClient(mPaymentHandlerWebContents));
 
-        mPaymentHandlerWebContents
-                .getNavigationController()
-                .loadUrl(new LoadUrlParams(url.getSpec()));
+        LoadUrlParams params = new LoadUrlParams(url.getSpec());
+        if (PaymentFeatureList.isEnabled(
+                PaymentFeatureList.PAYMENT_HANDLER_DIALOG_USE_INITIATOR_IN_URL_LOAD)) {
+            params.setInitiatorOrigin(
+                    Origin.create(paymentRequestWebContents.getLastCommittedUrl()));
+        }
+        mPaymentHandlerWebContents.getNavigationController().loadUrl(params);
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java
index 52bf1fb..0c1a5717 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java
@@ -40,6 +40,7 @@
 import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.Features.EnableFeatures;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.compositor.overlay_panel.OverlayPanel.StateChangeReason;
@@ -53,9 +54,11 @@
 import org.chromium.chrome.test.transit.page.WebPageStation;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport;
 import org.chromium.components.embedder_support.util.UrlConstants;
+import org.chromium.components.payments.PaymentFeatureList;
 import org.chromium.components.payments.ui.InputProtector;
 import org.chromium.components.payments.ui.test_support.FakeClock;
 import org.chromium.content_public.browser.LoadUrlParams;
+import org.chromium.content_public.browser.NavigationHandle;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.content_public.browser.WebContentsObserver;
 import org.chromium.content_public.browser.test.util.DOMUtils;
@@ -64,6 +67,7 @@
 import org.chromium.net.test.ServerCertificate;
 import org.chromium.ui.base.DeviceFormFactor;
 import org.chromium.url.GURL;
+import org.chromium.url.Origin;
 
 import java.util.Arrays;
 import java.util.List;
@@ -144,16 +148,30 @@
         mClock = new FakeClock();
     }
 
-    private PaymentHandlerCoordinator createPaymentHandlerAndShow(ChromeTabbedActivity cta)
-            throws Throwable {
+    private PaymentHandlerCoordinator createPaymentHandler() throws Throwable {
         PaymentHandlerCoordinator paymentHandler = new PaymentHandlerCoordinator();
         paymentHandler.setInputProtectorForTest(new InputProtector(mClock));
+        return paymentHandler;
+    }
+
+    private void showPaymentHandler(
+            PaymentHandlerCoordinator paymentHandler, ChromeTabbedActivity cta) {
         ThreadUtils.runOnUiThreadBlocking(
                 () ->
                         paymentHandler.show(
                                 cta.getCurrentWebContents(),
                                 defaultPaymentAppUrl(),
                                 defaultUiObserver()));
+    }
+
+    private void showPaymentHandler(PaymentHandlerCoordinator paymentHandler) {
+        showPaymentHandler(paymentHandler, mDefaultActivity);
+    }
+
+    private PaymentHandlerCoordinator createPaymentHandlerAndShow(ChromeTabbedActivity cta)
+            throws Throwable {
+        PaymentHandlerCoordinator paymentHandler = createPaymentHandler();
+        showPaymentHandler(paymentHandler, cta);
         return paymentHandler;
     }
 
@@ -358,6 +376,42 @@
     @Test
     @SmallTest
     @Feature({"Payments"})
+    @EnableFeatures({PaymentFeatureList.PAYMENT_HANDLER_DIALOG_USE_INITIATOR_IN_URL_LOAD})
+    public void testInitiatorOriginSet() throws Throwable {
+        startDefaultServer();
+        mStartingPage = mStartingPage.loadWebPageProgrammatically(mServer.getURL("/"));
+
+        CallbackHelper startNavigationCallbackHelper = new CallbackHelper();
+        PaymentHandlerCoordinator paymentHandler = createPaymentHandler();
+
+        WebContentsObserver observer =
+                new WebContentsObserver() {
+                    @Override
+                    public void didStartNavigationInPrimaryMainFrame(NavigationHandle navigation) {
+                        Origin expectedOrigin =
+                                Origin.create(
+                                        mDefaultActivity
+                                                .getCurrentWebContents()
+                                                .getLastCommittedUrl());
+                        Assert.assertEquals(expectedOrigin, navigation.getInitiatorOrigin());
+                        startNavigationCallbackHelper.notifyCalled();
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.