Chrome · Payments
CVE-2026-8566
Logic Error in Payments
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/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.javachrome/android/javatests/src/org/chromium/chrome/browser/payments/ExpandablePaymentHandlerTest.java
Patch
From 4d76210c7828d2d67024ea1b3b0ba9ec7206d2a5 Mon Sep 17 00:00:00 2001 From: Jayden Nikifork <[email protected]> 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 <[email protected]> Commit-Queue: Jayden Nikifork <[email protected]> Reviewed-by: Xuehui Chen <[email protected]> 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.
References
On This Page