CVE-2026-3942
Overview
Background
- Media session `source_title`
- The string
MediaSessionImplbuilds from the playing page’s URL and exposes as the media’s source. The Picture-in-Picture overlay shows it as the origin (origin_for_testing()in the test) so the user knows which site owns the floating window. - Opaque origin
- A
url::Originwith no scheme/host/port tuple, as given to CSP-sandboxed documents and someabout:blankpopups.origin.GetURL()on an opaque origin produces no meaningful host to show. - Precursor origin
- The tuple an opaque origin was derived from, read via
GetTupleOrPrecursorTupleIfOpaque(). It lets the browser name the site that actually created an opaque context. - Opener chain
- The
WebContents::GetOpener()links from a popup back to the frame thatwindow.opened it.
Root Cause Analysis
In media_session_impl.cc, for non-data: URLs the media session’s source_title was computed as url_formatter::FormatUrl(url::Origin::Create(url).GetURL(), ...). The hunk does not show the enclosing function’s name. When the playing document had an opaque origin, this formatted an origin with no host, so the Picture-in-Picture window showed no recognizable site. A sandboxed page or an about:blank popup it opened could therefore put up a PiP window that did not truthfully attribute its content to the responsible site. The invariant violated is that security UI attached to a PiP window must always name a meaningful originating site.
The fix keeps the old behavior for non-opaque origins. For opaque ones it walks from the current web_contents() through GetOpener(), using a base::flat_set to stop on cycles. At each step it reads the last committed URL’s tuple or precursor and uses the first valid one as format_url. In the browser tests the window then displays example.com, or the closest ancestor another-site.com.
Attack Path
- Create an opaque-origin context
A page is served with
Content-Security-Policy: sandbox allow-scripts allow-popups, and it can alsowindow.open('about:blank')popups. Both setups appear in the regression tests. - Start PiP from the opaque context
Script in the popup creates a
<video>, plays it, and callsrequestPictureInPicture(). - Origin label degrades
Before the fix,
FormatUrl(url::Origin::Create(url).GetURL(), ...)was given an origin with no tuple, so the overlay did not show the true originating site. - User misattribution A floating, always-on-top PiP window with a missing or uninformative origin could be used to show content the user wrongly trusts or attributes to another site (inferred). The patch shows only the label degrading, not a specific spoofed label.
Impact Assessment
Changed Functions
| Function | Change | Notes |
|---|---|---|
ASSERT_TRUEchrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc |
modified |
Files Changed
chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cccontent/browser/media/session/media_session_impl.cc
Audit Directions
- Origin display from opaque originsSearch for other security UI (permission prompts, download bubbles, notification attribution, Document PiP, external-protocol dialogs) that formats
url::Origin::Create(url).GetURL()orGetLastCommittedOrigin()directly. Check what is shown when the origin is opaque. - Opener-derived attributionThe fallback trusts the opener’s last committed URL. Check whether an opener that has since navigated away can make the PiP window be credited to the wrong site, and whether a frame-level origin (rather than
WebContentsmain-frame URL) should be used for media playing in iframes. - Media-session metadata surfacesAudit other consumers of
MediaSessionImplmetadata (global media controls, lock-screen/OS media integration) for the same opaque-origin labelling gap.
Patch
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
index e9a1474..542bd7e 100644
--- a/content/browser/media/session/media_session_impl.cc
+++ b/content/browser/media/session/media_session_impl.cc
@@ -8,6 +8,7 @@
#include <memory>
#include <utility>
+#include "base/containers/flat_set.h"
#include "base/functional/bind.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -1986,8 +1987,38 @@
source_title =
content_client->GetLocalizedString(IDS_MEDIA_SESSION_DATA_SOURCE);
} else {
+ url::Origin origin = url::Origin::Create(url);
+ GURL format_url = origin.GetURL();
+
+ // If the origin is opaque, use its precursor origin if available.
+ // Otherwise, traverse the opener chain to find the closest ancestor with
+ // a valid precursor origin. This ensures we display a recognizable origin
+ // to the user.
+ if (origin.opaque()) {
+ WebContents* current_web_contents = web_contents();
+ base::flat_set<WebContents*> seen_web_contents;
+
+ while (current_web_contents &&
+ !seen_web_contents.contains(current_web_contents)) {
+ seen_web_contents.insert(current_web_contents);
+
+ url::Origin current_origin =
+ url::Origin::Create(current_web_contents->GetLastCommittedURL());
+ const auto& precursor =
+ current_origin.GetTupleOrPrecursorTupleIfOpaque();
+ if (precursor.IsValid()) {
+ format_url = precursor.GetURL();
+ break;
+ }
+
+ RenderFrameHost* opener = current_web_contents->GetOpener();
+ current_web_contents =
+ opener ? WebContents::FromRenderFrameHost(opener) : nullptr;
+ }
+ }
+
source_title = url_formatter::FormatUrl(
- url::Origin::Create(url).GetURL(),
+ format_url,
url_formatter::kFormatUrlOmitDefaults |
url_formatter::kFormatUrlOmitHTTPS |
url_formatter::kFormatUrlOmitTrivialSubdomains,
diff --git a/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
index 617f570..3135ccc 100644
--- a/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
@@ -9,6 +9,7 @@
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/scoped_observation.h"
+#include "base/strings/string_util.h"
#include "base/test/bind.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
@@ -2424,6 +2425,193 @@
EXPECT_TRUE(GetOverlayWindow()->AreTitleAndScrimVisibleForTesting());
}
+IN_PROC_BROWSER_TEST_F(VideoPictureInPictureWindowControllerBrowserTest,
+ SourceTitle_OpaqueFallback) {
+ const std::string kTestHost = "example.com";
+ const std::u16string kExpectedTitlePrefix = base::ASCIIToUTF16(kTestHost);
+
+ // Open a sandboxed page, which will have an opaque origin.
+ GURL sandboxed_main_url =
+ embedded_test_server()->GetURL(kTestHost,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), sandboxed_main_url));
+
+ content::WebContents* active_web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Verify the main frame has an opaque origin.
+ ASSERT_TRUE(active_web_contents->GetPrimaryMainFrame()
+ ->GetLastCommittedOrigin()
+ .opaque());
+
+ // Open an about:blank popup from the sandboxed main frame.
+ content::WebContents* popup_contents;
+ {
+ content::WebContentsAddedObserver new_contents_observer;
+ ASSERT_TRUE(ExecJs(active_web_contents, "window.open('about:blank');"));
+ popup_contents = new_contents_observer.GetWebContents();
+ }
+
+ // Verify that the popup also has an opaque origin
+ // and has established the opener relationship.
+ ASSERT_TRUE(
+ popup_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque());
+ ASSERT_EQ(active_web_contents->GetPrimaryMainFrame(),
+ popup_contents->GetOpener());
+
+ // Inject a video element and play it in the popup.
+ GURL video_url =
+ embedded_test_server()->GetURL(kTestHost, "/media/bear.webm");
+ std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ const video = document.createElement('video');
+ video.src = '$1';
+ video.loop = true;
+ document.body.appendChild(video);
+ video.play().then(() => video.requestPictureInPicture());
+ )",
+ {video_url.spec()}, nullptr);
+ ASSERT_TRUE(ExecJs(popup_contents, script));
+
+ // Wait until the Picture-in-Picture window is visible and its source title
+ // correctly falls back to the opener's origin (example.com).
+ SetUpWindowController(popup_contents);
+ ASSERT_TRUE(base::test::RunUntil([&]() {
+ auto* overlay_window = GetOverlayWindow();
+ return overlay_window && overlay_window->IsVisible() &&
+ overlay_window->origin_for_testing() &&
+ base::StartsWith(overlay_window->origin_for_testing()->GetText(),
+ kExpectedTitlePrefix);
+ }));
+}
+
+IN_PROC_BROWSER_TEST_F(VideoPictureInPictureWindowControllerBrowserTest,
+ SourceTitle_NestedOpaqueFallback) {
+ const std::string kTestHost = "example.com";
+ const std::u16string kExpectedTitlePrefix = base::ASCIIToUTF16(kTestHost);
+
+ // Open a sandboxed page, which will have an opaque origin.
+ GURL sandboxed_main_url =
+ embedded_test_server()->GetURL(kTestHost,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), sandboxed_main_url));
+
+ content::WebContents* active_web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Open an about:blank popup from the sandboxed main frame.
+ content::WebContents* popup1_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(active_web_contents, "window.open('about:blank');"));
+ popup1_contents = observer.GetWebContents();
+ }
+
+ // Open another about:blank popup from the first popup.
+ content::WebContents* popup2_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(popup1_contents, "window.open('about:blank');"));
+ popup2_contents = observer.GetWebContents();
+ }
+
+ // Inject a video element and play it in the nested popup.
+ GURL video_url =
+ embedded_test_server()->GetURL(kTestHost, "/media/bear.webm");
+ std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ const video = document.createElement('video');
+ video.src = '$1';
+ video.loop = true;
+ document.body.appendChild(video);
+ video.play().then(() => video.requestPictureInPicture());
+ )",
+ {video_url.spec()}, nullptr);
+ ASSERT_TRUE(ExecJs(popup2_contents, script));
+
+ // Wait until the Picture-in-Picture window is visible and its source title
+ // correctly falls back through the nested openers to the original origin
+ // (example.com).
+ SetUpWindowController(popup2_contents);
+ ASSERT_TRUE(base::test::RunUntil([&]() {
+ auto* overlay_window = GetOverlayWindow();
+ return overlay_window && overlay_window->IsVisible() &&
+ overlay_window->origin_for_testing() &&
+ base::StartsWith(overlay_window->origin_for_testing()->GetText(),
+ kExpectedTitlePrefix);
+ }));
+}
+
+IN_PROC_BROWSER_TEST_F(VideoPictureInPictureWindowControllerBrowserTest,
+ SourceTitle_ClosestAncestorFallback) {
+ const std::string kHost1 = "example.com";
+ const std::string kHost2 = "another-site.com";
+ const std::u16string kExpectedTitlePrefix = base::ASCIIToUTF16(kHost2);
+
+ // Open Host 1 sandboxed.
+ GURL url1 =
+ embedded_test_server()->GetURL(kHost1,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
+ content::WebContents* active_web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Open about:blank (Popup 1).
+ content::WebContents* popup1_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(active_web_contents, "window.open('about:blank');"));
+ popup1_contents = observer.GetWebContents();
+ }
+
+ // Navigate Popup 1 to Host 2 sandboxed.
+ GURL url2 =
+ embedded_test_server()->GetURL(kHost2,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ {
+ content::TestNavigationObserver nav_observer(popup1_contents);
+ ASSERT_TRUE(ExecJs(popup1_contents,
+ base::StringPrintf("window.location.href = '%s';",
+ url2.spec().c_str())));
+ nav_observer.Wait();
+ }
+
+ // Open another about:blank (Popup 2) from Popup 1 (Host 2).
+ content::WebContents* popup2_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(popup1_contents, "window.open('about:blank');"));
+ popup2_contents = observer.GetWebContents();
+ }
+
+ // Play video in Popup 2.
+ GURL video_url = embedded_test_server()->GetURL(kHost2, "/media/bear.webm");
+ std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ const video = document.createElement('video');
+ video.src = '$1';
+ video.loop = true;
+ document.body.appendChild(video);
+ video.play().then(() => video.requestPictureInPicture());
+ )",
+ {video_url.spec()}, nullptr);
+ ASSERT_TRUE(ExecJs(popup2_contents, script));
+
+ // Verify source title is Host 2 (the closest opener with a valid precursor).
+ SetUpWindowController(popup2_contents);
+ ASSERT_TRUE(base::test::RunUntil([&]() {
+ auto* overlay_window = GetOverlayWindow();
+ return overlay_window && overlay_window->IsVisible() &&
+ overlay_window->origin_for_testing() &&
+ base::StartsWith(overlay_window->origin_for_testing()->GetText(),
+ kExpectedTitlePrefix);
+ }));
+}
+
struct InteractionTestParam {
ui::EventType event_type;
bool title_should_be_visible;
Regression Test / PoC
diff --git a/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
index 617f570..3135ccc 100644
--- a/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/video_picture_in_picture_window_controller_browsertest.cc
@@ -9,6 +9,7 @@
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/scoped_observation.h"
+#include "base/strings/string_util.h"
#include "base/test/bind.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
@@ -2424,6 +2425,193 @@
EXPECT_TRUE(GetOverlayWindow()->AreTitleAndScrimVisibleForTesting());
}
+IN_PROC_BROWSER_TEST_F(VideoPictureInPictureWindowControllerBrowserTest,
+ SourceTitle_OpaqueFallback) {
+ const std::string kTestHost = "example.com";
+ const std::u16string kExpectedTitlePrefix = base::ASCIIToUTF16(kTestHost);
+
+ // Open a sandboxed page, which will have an opaque origin.
+ GURL sandboxed_main_url =
+ embedded_test_server()->GetURL(kTestHost,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), sandboxed_main_url));
+
+ content::WebContents* active_web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Verify the main frame has an opaque origin.
+ ASSERT_TRUE(active_web_contents->GetPrimaryMainFrame()
+ ->GetLastCommittedOrigin()
+ .opaque());
+
+ // Open an about:blank popup from the sandboxed main frame.
+ content::WebContents* popup_contents;
+ {
+ content::WebContentsAddedObserver new_contents_observer;
+ ASSERT_TRUE(ExecJs(active_web_contents, "window.open('about:blank');"));
+ popup_contents = new_contents_observer.GetWebContents();
+ }
+
+ // Verify that the popup also has an opaque origin
+ // and has established the opener relationship.
+ ASSERT_TRUE(
+ popup_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin().opaque());
+ ASSERT_EQ(active_web_contents->GetPrimaryMainFrame(),
+ popup_contents->GetOpener());
+
+ // Inject a video element and play it in the popup.
+ GURL video_url =
+ embedded_test_server()->GetURL(kTestHost, "/media/bear.webm");
+ std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ const video = document.createElement('video');
+ video.src = '$1';
+ video.loop = true;
+ document.body.appendChild(video);
+ video.play().then(() => video.requestPictureInPicture());
+ )",
+ {video_url.spec()}, nullptr);
+ ASSERT_TRUE(ExecJs(popup_contents, script));
+
+ // Wait until the Picture-in-Picture window is visible and its source title
+ // correctly falls back to the opener's origin (example.com).
+ SetUpWindowController(popup_contents);
+ ASSERT_TRUE(base::test::RunUntil([&]() {
+ auto* overlay_window = GetOverlayWindow();
+ return overlay_window && overlay_window->IsVisible() &&
+ overlay_window->origin_for_testing() &&
+ base::StartsWith(overlay_window->origin_for_testing()->GetText(),
+ kExpectedTitlePrefix);
+ }));
+}
+
+IN_PROC_BROWSER_TEST_F(VideoPictureInPictureWindowControllerBrowserTest,
+ SourceTitle_NestedOpaqueFallback) {
+ const std::string kTestHost = "example.com";
+ const std::u16string kExpectedTitlePrefix = base::ASCIIToUTF16(kTestHost);
+
+ // Open a sandboxed page, which will have an opaque origin.
+ GURL sandboxed_main_url =
+ embedded_test_server()->GetURL(kTestHost,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), sandboxed_main_url));
+
+ content::WebContents* active_web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Open an about:blank popup from the sandboxed main frame.
+ content::WebContents* popup1_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(active_web_contents, "window.open('about:blank');"));
+ popup1_contents = observer.GetWebContents();
+ }
+
+ // Open another about:blank popup from the first popup.
+ content::WebContents* popup2_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(popup1_contents, "window.open('about:blank');"));
+ popup2_contents = observer.GetWebContents();
+ }
+
+ // Inject a video element and play it in the nested popup.
+ GURL video_url =
+ embedded_test_server()->GetURL(kTestHost, "/media/bear.webm");
+ std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ const video = document.createElement('video');
+ video.src = '$1';
+ video.loop = true;
+ document.body.appendChild(video);
+ video.play().then(() => video.requestPictureInPicture());
+ )",
+ {video_url.spec()}, nullptr);
+ ASSERT_TRUE(ExecJs(popup2_contents, script));
+
+ // Wait until the Picture-in-Picture window is visible and its source title
+ // correctly falls back through the nested openers to the original origin
+ // (example.com).
+ SetUpWindowController(popup2_contents);
+ ASSERT_TRUE(base::test::RunUntil([&]() {
+ auto* overlay_window = GetOverlayWindow();
+ return overlay_window && overlay_window->IsVisible() &&
+ overlay_window->origin_for_testing() &&
+ base::StartsWith(overlay_window->origin_for_testing()->GetText(),
+ kExpectedTitlePrefix);
+ }));
+}
+
+IN_PROC_BROWSER_TEST_F(VideoPictureInPictureWindowControllerBrowserTest,
+ SourceTitle_ClosestAncestorFallback) {
+ const std::string kHost1 = "example.com";
+ const std::string kHost2 = "another-site.com";
+ const std::u16string kExpectedTitlePrefix = base::ASCIIToUTF16(kHost2);
+
+ // Open Host 1 sandboxed.
+ GURL url1 =
+ embedded_test_server()->GetURL(kHost1,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
+ content::WebContents* active_web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
+
+ // Open about:blank (Popup 1).
+ content::WebContents* popup1_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(active_web_contents, "window.open('about:blank');"));
+ popup1_contents = observer.GetWebContents();
+ }
+
+ // Navigate Popup 1 to Host 2 sandboxed.
+ GURL url2 =
+ embedded_test_server()->GetURL(kHost2,
+ "/set-header?Content-Security-Policy: "
+ "sandbox allow-scripts allow-popups");
+ {
+ content::TestNavigationObserver nav_observer(popup1_contents);
+ ASSERT_TRUE(ExecJs(popup1_contents,
+ base::StringPrintf("window.location.href = '%s';",
+ url2.spec().c_str())));
+ nav_observer.Wait();
+ }
+
+ // Open another about:blank (Popup 2) from Popup 1 (Host 2).
+ content::WebContents* popup2_contents;
+ {
+ content::WebContentsAddedObserver observer;
+ ASSERT_TRUE(ExecJs(popup1_contents, "window.open('about:blank');"));
+ popup2_contents = observer.GetWebContents();
+ }
+
+ // Play video in Popup 2.
+ GURL video_url = embedded_test_server()->GetURL(kHost2, "/media/bear.webm");
+ std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ const video = document.createElement('video');
+ video.src = '$1';
+ video.loop = true;
+ document.body.appendChild(video);
+ video.play().then(() => video.requestPictureInPicture());
+ )",
+ {video_url.spec()}, nullptr);
+ ASSERT_TRUE(ExecJs(popup2_contents, script));
+
+ // Verify source title is Host 2 (the closest opener with a valid precursor).
+ SetUpWindowController(popup2_contents);
+ ASSERT_TRUE(base::test::RunUntil([&]() {
+ auto* overlay_window = GetOverlayWindow();
+ return overlay_window && overlay_window->IsVisible() &&
+ overlay_window->origin_for_testing() &&
+ base::StartsWith(overlay_window->origin_for_testing()->GetText(),
+ kExpectedTitlePrefix);
+ }));
+}
+
struct InteractionTestParam {
ui::EventType event_type;
bool title_should_be_visible;
Original Bug Report
PIP Origin Attribution Missing When Triggered from `about:blank` via Injected JavaScript
Report description
PIP Origin Attribution Missing When Triggered from about:blank via Injected JavaScript
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
Summary
When a popup window is opened at about:blank and dynamically populated using JavaScript from its opener, initiating a Picture-in-Picture (PiP) request from this context results in missing or incorrect origin attribution in the PiP window UI. Instead of displaying the actual execution origin, the PiP window appears without any visible site attribution.
Steps to Reproduce
- Open the PoC URL: https://bughunter-6.github.io/SummaTest/emptytest.html
- Click the button to open the popup window.
- The popup opens at
about:blankand is populated via injected JavaScript from the opener. - Click the Picture-in-Picture button inside the popup.
- Observe the PiP window UI.
- The PiP window does not display any origin or site attribution.
POC URL: https://drive.google.com/file/d/1AJyG06LioG1PsaPaX5ZSVJXceCHe61P8/view?usp=sharing
Observed Behavior
The Picture-in-Picture window launches without showing the true origin responsible for the PiP request when the request is triggered from an about:blank document, despite the JavaScript executing under the opener’s origin.
Expected Behavior
The PiP window should consistently and clearly display the actual execution origin that initiated Picture-in-Picture, even if the visible document URL is about:blank. Blank or origin-less PiP UI should be avoided to ensure proper user awareness.
Impact analysis
This behavior allows attacker-controlled sites to present PiP content without exposing the real originating domain, enabling origin confusion and deceptive overlays. Users may trust a PiP window believing it is system-level or neutral, while it is actually controlled by a malicious site. An attacker could abuse this to display persistent phishing prompts, fake system alerts, or misleading media overlays while masking the true source. When combined with fullscreen or pointer lock, this significantly increases the risk of UI spoofing and social engineering attacks.
The cause
What version of Chrome have you found the security issue in?
Version 143.0.7499.193 (Official Build) (arm64)
Is the security issue related to a crash?
No, it is not related to a crash.
Choose the type of vulnerability
Security UI Spoofing
How would you like to be publicly acknowledged for your report?
Barath Stalin K( https://in.linkedin.com/in/barathstalin)