CVE-2025-0442
Overview
Background
- PaymentRequest UI
- The desktop dialog (
PaymentRequestDialogView), including Secure Payment Confirmation (SPC) authentication and no-credentials flows, that collects payment and authentication input from the user during aPaymentRequesttransaction. - Picture-in-picture (PiP) occlusion
- A condition in which a floating PiP video window is rendered on top of another widget, tracked in Chrome by the
PictureInPictureOcclusionObserverinterface andScopedPictureInPictureOcclusionObservationhelper. - Web-modal dialog
- A tab-modal
views::Widgetcreated viaconstrained_window::ShowWebModalDialogViews, which the payment dialog uses so that it is constrained to the initiatingweb_contents. - UI spoofing/overlay risk
- A class of logic error where security-sensitive UI can be visually covered or impersonated by attacker-influenced content, misleading the user about what they are confirming.
Root Cause Analysis
Before the patch, PaymentRequestDialogView and the SPC dialog views established themselves as web-modal widgets but never observed picture-in-picture occlusion, so a PiP video window could be painted directly on top of the payment or SPC authentication surface. This violated the security invariant that a security-sensitive confirmation dialog must be the topmost, unobstructed element the user interacts with, since the modal grab only guarantees interaction constraint within the tab, not z-order supremacy over always-on-top PiP windows. Because the dialog remained enabled and visible-yet-covered, a user could authorize a payment or SPC assertion while looking at PiP content overlaying (and effectively hiding) the real UI.
The fix makes the dialog implement PictureInPictureOcclusionObserver and register a ScopedPictureInPictureOcclusionObservation on its widget, so occlusion transitions are delivered to OnOcclusionStateChanged. When occlusion is reported, the dialog immediately calls SetEnabled(false) to block further input and posts a task to CloseDialog, closing the compromised surface. Posting the close as a task (rather than closing synchronously) is required because occlusion can fire during initial show, when synchronous teardown is unsupported.
Attack Path
- Initiate a payment flow
A page the user is visiting calls the Payment Request or Secure Payment Confirmation API, causing Chrome to display the modal
PaymentRequestDialogViewor SPC dialog. - Open a picture-in-picture window Attacker-controlled content triggers a picture-in-picture video window, which is rendered always-on-top and independent of the tab-modal constraint.
- Position PiP over the dialog The PiP window is placed so it occludes the security-sensitive payment or authentication surface, hiding or replacing what the user sees while the dialog stays enabled underneath.
- Induce a confirmation The user, misled about what is actually on screen, interacts with or confirms the still-active dialog, authorizing a payment or SPC assertion they did not intend.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifchrome/browser/ui/views/payments/payment_request_dialog_view.cc |
modified | |
PaymentRequestDialogViewchrome/browser/ui/views/payments/payment_request_dialog_view.h |
modified | |
ifchrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.cc |
modified | |
SecurePaymentConfirmationDialogViewchrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h |
modified |
Files Changed
chrome/browser/ui/views/payments/payment_request_dialog_view.ccchrome/browser/ui/views/payments/payment_request_dialog_view.hchrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.ccchrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.ccchrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h
Audit Directions
- Modality without z-order guaranteesAudit other security-sensitive dialogs (permission prompts, credential and WebAuthn UIs) that rely only on web-/tab-modality and verify they also handle always-on-top picture-in-picture occlusion.
- Occlusion observer coverageSearch for widgets that display trusted or confirmation UI but do not register a
ScopedPictureInPictureOcclusionObservation, since these can be overlaid by PiP. - Synchronous-close assumptions during showReview UI that reacts to state changes (occlusion, focus loss, visibility) to ensure teardown is posted rather than performed synchronously when the change can fire during initial display.
Patch
From 399b9db4d1f3dcd34554ba54cf2c54400ad4053a Mon Sep 17 00:00:00 2001
From: Rouslan Solomakhin <rouslan@chromium.org>
Date: Fri, 25 Oct 2024 13:08:17 +0000
Subject: [PATCH] Close PaymentRequest UI when picture-in-picture occludes it.
Before this patch, picture-in-picture video could be displayed on top of
the PaymentRequest UI (including SPC) which could confuse users.
This patch adds a picture-in-picture occlusion observer to the desktop
PaymentRequest UI, SPC authentication UI, and SPC no-credentials UI.
When a UI is occluded, it is immediately disabled and a task to close
the UI is posted. Posting the task is necessary because the occlusion
could happen when initially showing the UI, when closing the UI is not
supported.
After this patch, PaymentRequest desktop UI is hidden when a
picture-in-picture video occludes it.
Bug: 40940854, 297885233, 40280009
Change-Id: I4430e573227d746a9a246f727b48798e4590198d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5955634
Commit-Queue: Rouslan Solomakhin <rouslan@chromium.org>
Reviewed-by: Nick Navarro <npnavarro@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1373855}
---
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
index 819cc3aa..25cee96 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.cc
@@ -111,6 +111,7 @@
views::Widget* widget = constrained_window::ShowWebModalDialogViews(
this, request_->web_contents());
extensions::SecurityDialogTracker::GetInstance()->AddSecurityDialog(widget);
+ occlusion_observation_.Observe(widget);
}
void PaymentRequestDialogView::CloseDialog() {
@@ -578,6 +579,15 @@
}
}
+void PaymentRequestDialogView::OnOcclusionStateChanged(bool occluded) {
+ if (occluded) {
+ SetEnabled(false);
+ base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+ FROM_HERE, base::BindOnce(&PaymentRequestDialogView::CloseDialog,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
void PaymentRequestDialogView::ResizeDialogWindow() {
if (GetWidget() && request_->web_contents()) {
constrained_window::UpdateWebContentsModalDialogPosition(
diff --git a/chrome/browser/ui/views/payments/payment_request_dialog_view.h b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
index 304c964..8fcd4fa 100644
--- a/chrome/browser/ui/views/payments/payment_request_dialog_view.h
+++ b/chrome/browser/ui/views/payments/payment_request_dialog_view.h
@@ -11,6 +11,8 @@
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h"
+#include "chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h"
#include "chrome/browser/ui/views/payments/view_stack.h"
#include "components/payments/content/initialization_task.h"
#include "components/payments/content/payment_request_dialog.h"
@@ -48,7 +50,8 @@
class PaymentRequestDialogView : public views::DialogDelegateView,
public PaymentRequestDialog,
public PaymentRequestSpec::Observer,
- public InitializationTask::Observer {
+ public InitializationTask::Observer,
+ public PictureInPictureOcclusionObserver {
METADATA_HEADER(PaymentRequestDialogView, views::DialogDelegateView)
public:
@@ -204,6 +207,9 @@
void ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) override;
+ // PictureInPictureOcclusionObserver
+ void OnOcclusionStateChanged(bool occluded) override;
+
// The PaymentRequest object that initiated this dialog.
base::WeakPtr<PaymentRequest> request_;
ControllerMap controller_map_;
@@ -231,6 +237,8 @@
// handler window.
int payment_handler_window_height_ = 0;
+ ScopedPictureInPictureOcclusionObservation occlusion_observation_{this};
+
base::WeakPtrFactory<PaymentRequestDialogView> weak_ptr_factory_{this};
};
diff --git a/chrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc
new file mode 100644
index 0000000..4c31b040
--- /dev/null
+++ b/chrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc
@@ -0,0 +1,40 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h"
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace payments {
+namespace {
+
+using PaymentRequestPictureInPictureOcclusionTest =
+ PaymentRequestBrowserTestBase;
+
+IN_PROC_BROWSER_TEST_F(PaymentRequestPictureInPictureOcclusionTest,
+ OcclusionClosesDialog) {
+ std::string a_method_name;
+ InstallPaymentApp("a.com", "/payment_request_success_responder.js",
+ &a_method_name);
+ std::string b_method_name;
+ InstallPaymentApp("b.com", "/payment_request_success_responder.js",
+ &b_method_name);
+ NavigateTo("/payment_request_no_shipping_test.html");
+ InvokePaymentRequestUIWithJs(content::JsReplace(
+ "buyWithMethods([{supportedMethods:$1}, {supportedMethods:$2}]);",
+ a_method_name, b_method_name));
+ ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+
+ static_cast<PictureInPictureOcclusionObserver*>(dialog_view())
+ ->OnOcclusionStateChanged(/*occluded=*/true);
+
+ ASSERT_TRUE(WaitForObservedEvent());
+}
+
+} // namespace
+} // namespace payments
diff --git a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.cc b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.cc
index b5f26d249..1dad9bb 100644
--- a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.cc
+++ b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h"
#include "base/metrics/histogram_functions.h"
+#include "base/task/single_thread_task_runner.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/extensions/security_dialog_tracker.h"
@@ -142,6 +143,7 @@
views::Widget* widget =
constrained_window::ShowWebModalDialogViews(this, web_contents);
extensions::SecurityDialogTracker::GetInstance()->AddSecurityDialog(widget);
+ occlusion_observation_.Observe(widget);
// The progress bar doesn't exist until after ShowWebModalDialogViews, so we
// have to update it here in case it starts visible.
@@ -513,6 +515,17 @@
return row;
}
+void SecurePaymentConfirmationDialogView::OnOcclusionStateChanged(
+ bool occluded) {
+ if (occluded) {
+ SetEnabled(false);
+ base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&SecurePaymentConfirmationDialogView::HideDialog,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
BEGIN_METADATA(SecurePaymentConfirmationDialogView)
END_METADATA
diff --git a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h
index a60e4065..2447c53 100644
--- a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h
+++ b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h
@@ -7,6 +7,8 @@
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
+#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h"
+#include "chrome/browser/picture_in_picture/scoped_picture_in_picture_occlusion_observation.h"
#include "components/payments/content/secure_payment_confirmation_view.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/button.h"
@@ -24,7 +26,8 @@
// the SecurePaymentConfirmationController.
class SecurePaymentConfirmationDialogView
: public SecurePaymentConfirmationView,
- public views::DialogDelegateView {
+ public views::DialogDelegateView,
+ public PictureInPictureOcclusionObserver {
Regression Test / PoC
diff --git a/chrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc
new file mode 100644
index 0000000..4c31b040
--- /dev/null
+++ b/chrome/browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc
@@ -0,0 +1,40 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h"
+#include "chrome/browser/ui/views/payments/payment_request_browsertest_base.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace payments {
+namespace {
+
+using PaymentRequestPictureInPictureOcclusionTest =
+ PaymentRequestBrowserTestBase;
+
+IN_PROC_BROWSER_TEST_F(PaymentRequestPictureInPictureOcclusionTest,
+ OcclusionClosesDialog) {
+ std::string a_method_name;
+ InstallPaymentApp("a.com", "/payment_request_success_responder.js",
+ &a_method_name);
+ std::string b_method_name;
+ InstallPaymentApp("b.com", "/payment_request_success_responder.js",
+ &b_method_name);
+ NavigateTo("/payment_request_no_shipping_test.html");
+ InvokePaymentRequestUIWithJs(content::JsReplace(
+ "buyWithMethods([{supportedMethods:$1}, {supportedMethods:$2}]);",
+ a_method_name, b_method_name));
+ ResetEventWaiter(DialogEvent::DIALOG_CLOSED);
+
+ static_cast<PictureInPictureOcclusionObserver*>(dialog_view())
+ ->OnOcclusionStateChanged(/*occluded=*/true);
+
+ ASSERT_TRUE(WaitForObservedEvent());
+}
+
+} // namespace
+} // namespace payments
diff --git a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc
index abad5de..e3d5f023 100644
--- a/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view_browsertest.cc
@@ -5,12 +5,16 @@
#include "chrome/browser/ui/views/payments/secure_payment_confirmation_dialog_view.h"
#include <optional>
+#include <utility>
+#include "base/functional/callback.h"
+#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "cc/test/pixel_comparator.h"
#include "cc/test/pixel_test_utils.h"
#include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
@@ -310,7 +314,14 @@
}
// SecurePaymentConfirmationDialogView::ObserverForTest:
- void OnDialogClosed() override { dialog_closed_ = true; }
+ void OnDialogClosed() override {
+ dialog_closed_ = true;
+ if (dialog_closed_callback_) {
+ std::move(dialog_closed_callback_).Run();
+ }
+ }
+
+ // SecurePaymentConfirmationDialogView::ObserverForTest:
void OnConfirmButtonPressed() override { confirm_pressed_ = true; }
void OnCancelButtonPressed() override { cancel_pressed_ = true; }
void OnOptOutClicked() override { opt_out_clicked_ = true; }
@@ -328,6 +339,7 @@
bool opt_out_clicked_ = false;
base::HistogramTester histogram_tester_;
+ base::OnceClosure dialog_closed_callback_;
base::WeakPtrFactory<SecurePaymentConfirmationDialogViewTest>
weak_ptr_factory_{this};
@@ -624,6 +636,22 @@
EXPECT_TRUE(opt_out_clicked_);
}
+// Occlusion by picture-in-picture video should dismiss the SPC authentication
+// dialog.
+IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationDialogViewTest,
+ PictureInPictureOcclusionClosesTheDialog) {
+ CreateModel();
+ InvokeSecurePaymentConfirmationUI();
+ base::RunLoop run_loop;
+ dialog_closed_callback_ = run_loop.QuitClosure();
+
+ static_cast<PictureInPictureOcclusionObserver*>(test_delegate_->dialog_view())
+ ->OnOcclusionStateChanged(/*occluded=*/true);
+
+ run_loop.Run();
+ EXPECT_TRUE(dialog_closed_);
+}
+
// A variant of SecurePaymentConfirmationDialogViewTest that enables the network
// and issuer rows feature, and verifies their contents.
class SecurePaymentConfirmationDialogViewNetworkAndIssuerIconsTest
diff --git a/chrome/browser/ui/views/payments/secure_payment_confirmation_no_creds_dialog_view_browsertest.cc b/chrome/browser/ui/views/payments/secure_payment_confirmation_no_creds_dialog_view_browsertest.cc
index cdf280b..b8febbb 100644
--- a/chrome/browser/ui/views/payments/secure_payment_confirmation_no_creds_dialog_view_browsertest.cc
+++ b/chrome/browser/ui/views/payments/secure_payment_confirmation_no_creds_dialog_view_browsertest.cc
@@ -4,8 +4,13 @@
#include "chrome/browser/ui/views/payments/secure_payment_confirmation_no_creds_dialog_view.h"
+#include <utility>
+
+#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
+#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/picture_in_picture/picture_in_picture_occlusion_observer.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
#include "components/payments/content/secure_payment_confirmation_no_creds_model.h"
@@ -76,7 +81,14 @@
}
// SecurePaymentConfirmationNoCredsDialogView::ObserverForTest
- void OnDialogClosed() override { dialog_closed_ = true; }
+ void OnDialogClosed() override {
+ dialog_closed_ = true;
+ if (dialog_closed_callback_) {
+ std::move(dialog_closed_callback_).Run();
+ }
+ }
+
+ // SecurePaymentConfirmationNoCredsDialogView::ObserverForTest
void OnOptOutClicked() override { opt_out_clicked_ = true; }
protected:
@@ -86,6 +98,8 @@
bool dialog_closed_ = false;
bool opt_out_clicked_ = false;
+
+ base::OnceClosure dialog_closed_callback_;
};
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationNoCredsDialogViewTest,
@@ -159,6 +173,21 @@
EXPECT_TRUE(opt_out_clicked_);
}
+// Occlusion by picture-in-picture video should dismiss the SPC no-credentials
+// dialog.
+IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationNoCredsDialogViewTest,
+ PictureInPictureOcclusionClosesTheDialog) {
+ CreateAndShowDialog(u"merchant.example", /*show_opt_out=*/true);
+ base::RunLoop run_loop;
+ dialog_closed_callback_ = run_loop.QuitClosure();
+
+ static_cast<PictureInPictureOcclusionObserver*>(dialog_view_.get())
+ ->OnOcclusionStateChanged(/*occluded=*/true);
+
+ run_loop.Run();
+ EXPECT_TRUE(dialog_closed_);
+}
+
class SecurePaymentConfirmationNoCredsDialogViewWithInlineNetworkAndIssuerTest
: public SecurePaymentConfirmationNoCredsDialogViewTest {
public:
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ea09666c..644b8da 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -4501,6 +4501,7 @@
"../browser/ui/views/payments/payment_request_no_update_with_browsertest.cc",
"../browser/ui/views/payments/payment_request_payment_app_browsertest.cc",
"../browser/ui/views/payments/payment_request_payment_response_browsertest.cc",
+ "../browser/ui/views/payments/payment_request_picture_in_picture_occlusion_browsertest.cc",
"../browser/ui/views/payments/payment_request_retry_browsertest.cc",
"../browser/ui/views/payments/payment_request_sheet_controller_browsertest.cc",
"../browser/ui/views/payments/payment_request_shipping_address_instance_browsertest.cc",
Original Bug Report
Security: Bypass the Protection of PaymentRequest dialog saved chrome Data, Bypass of Issue 1403539
VULNERABILITY DETAILS :
This Issue is an interesting Bypass for (https://crbug.com/chromium/1403539) and i’ve used same attack vector of (https://crbug.com/chromium/1358647) that recently fixed , and made a very convincing PoC , which is similar to real life attack scenario.
**(so Please Add Same Folks of 1403539 to take the ownership of this issue)**
**Please Add Meduim Severity as per Severity Guidelines for Security Issues https://www.chromium.org/developers/severity-guidelines/#medium-severity,referencing to Main Issue Bypassed before https://crbug.com/chromium/1403539 **
This is a report to a security vulnerability in google chrome/chromium browser as high-quality report with functional exploit. this vulnerability allows attackers to steal saved data which is used in payment sheet dialog UI (shipping Address Saved data) like addresses, e-mail addresses, telephone numbers,…etc from Chrome (Chrome Saved Data).
=====================
VERSION :
Exploit tested with the following properties:
Google Chrome Version: 120.0.6090.0
Channel:Dev
Milestone: 120
Branch: 6090
Branch Base Position: 1215263
Google Chrome: 120.0.6090.0 (Official Build) dev (64-bit)
Revision: 6ddf75e883b7682c7c4f262b00ba04df8bd1e35e-refs/branch-heads/6090@{#1}
OS: Linux
Google Chrome Version: 120.0.6051.2
Channel: Dev
Milestone: 120
Branch:6051
Branch Base Position: 1206341
Google Chrome: 120.0.6051.2 (Official Build) dev (64-bit) 0
Revision: 75e545cf7ce76506ad3d2a5736ef28053af4a7f7-refs/branch- heads/6051@{#4}
OS: Linux
Bisection:
[1]- https://chromium.googlesource.com/chromium/src/+/87cf1589bb30dde902d74657840c8486b605a9b1
which introduced at https://crbug.com/chromium/1358647 as a part of fix there but we can benfit from this CL here , this Commit introduces
Add GetWindowBounds for PictureInPicture
The window bounds would be used to check for any overlaps with the
Autofill popup in the next CLs.
this Commit is a part of fixing this issue , as we need to check intersection between picture in picture window bounds and payment Sheet dialog UI , if there is intersection between them we should dismiss this Dialog immediately to protect user from interacting with the UI without being aware, or seeing it at all.
the above Commit used in Hiding Autofill popup while intersection with picture in picture overlay as introduced in the following commit which may help you how commit [1] is used there
[2]- https://chromium-review.googlesource.com/c/chromium/src/+/4737994
Hide Autofill Popup if hidden behind Pip window
====================
Root Cause Analysis:
Idea of Attack and How Attack works:
————————- ———–
after landing to main Poc at https://vrphunt.com/chrome/payment-spf/payment-poc-spoofing.html this poc simulates an online gaming website for different games , and user can scroll and select any of them , and once user select(click on) any game image this what likely happening in details:
1-Document PIP Window appears with the Clicked Game (selected by user), which have consistent UI to Payment Sheet Color , and user will feel that he/she near playing the game (I made it very convincing) :) to match real life attack.
2-The Game PIP document shown have a Click to start button to let user Start loading this game , and Once this button Clicked
A) popup window will appear under this Document-PIP Overlay with same Style , and seems to be a part of this overlay, and at same time Loading progress bar start loading game for another convincing step.
B) at the time of showing progress bar there are some game Instruction shown to Start (Press ENTER , ans Click Continue )
, at this point the popup behind the PIP overlay is always focused and listen fot the key events , so when user press enter it will trigger Payment sheet to be Shown behind the PIP overlay, and clicking Continue will accept the payment information selected inside the payment sheet, and sending them to attacker Side.
PTL to Poc Video Attached for Repro.
=====================
REPRODUCTION CASE :
the exploit use a vulnerability in showing of cache of input fields. your browser suggests the saved entries of input fields like saved user logins (username, email, phone number…) or cached search word any similar entered things.
nobody will send critical information to unknown sites. but this can be hide by full bypassing the visibility of all fields and suggests. in this case nobody are able to notice that they are sending their data to unknown attackers.
=====================
REPRODUCTION STEPS:
(Play an Online game to get hijacked any saved payment shipping info like Addresses ,email,telephone,address,etc…..)
**Before Repro you can add some data under chrome://settings/addresses and add some records
1- Visit https://vrphunt.com/chrome/payment-spf/payment-poc-spoofing.html (Scroll and select your GAME)
2- Game Window (PIP document) will shown ,Click Click to Start button to start loading
3- Follow Game Instructions (Press Enter and Continue).
** Payment sheet data (Saved in chrome) Will be shown in the hidden popup window , Which Could be sent to Attacker Remote Side **
- Feel free to test with Online POC , Also Offline File is also attached.
==========================
Observed (What’s Go wrong):
===========================
Payment dialog sheet (UI) can be hidden, as popup not visible to user and fully Covered by Doument-Picture-in-Picture Overlay and this bypasses chrome security measures in sensetive data UI (Payment sheet UI), which contains user Sensitive data saved in Chrome.
Expected:
Sensitive browser UI (Payment dialog sheet (UI)) is always visible to user ,so Hide Payment sheet if it overlaps with Picture in Picture Overlay.
=====================
Mitigation:
We need to Check whether Payment dialog sheet (UI) overlaps with picture-in-picture window , and if so Hide the Payment dialog sheet (UI) immediately , with help of mentioned Commit[1] above.
-All POC Videos Attached, Stable and DEV Channels
-All POc Files Attached , Feel free to test with Online POC.
-if you want to test with your server you need to host the file at https server (Online is Better).
=====================
CREDIT INFORMATION
Reporter credit: Ahmed ElMasry
Thank you for your attention. with kind Regards
Payments-Leak-Info-Linux-DEV-V120-2023-11-08_13-55-43.mp4Payments-Leak-Info-Linux-Stable-V118-2023-11-08_13-50-52.mp4Repro-V118-Stable -Linux2023-11-09_09-21-44.mp4Repro-V120-DEV-Linux--2023-11-09_09-24-10.mp4Screenshot 2023-11-09 at 3.08.40 PM.pngScreenshot_20241029-172947.pngScreenshot_20241029-184710.pngpayment-poc-spoofing.htmlpayment-pop.html
- https://chromium-review.googlesource.com/c/chromium/src/+/4737994
- https://chromium.googlesource.com/chromium/src/+/87cf1589bb30dde902d74657840c8486b605a9b1
- https://crbug.com/chromium/1358647
- https://crbug.com/chromium/1403539
- https://vrphunt.com/chrome/payment-spf/payment-poc-spoofing.html
- https://www.chromium.org/developers/severity-guidelines/#medium-severity