Low chrome Logic Error 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactIncorrect security UI in Global Media Controls
DescriptionIncorrect security UI in Global Media Controls
ComponentGlobal Media Controls
Bug ClassLogic Error
Tracker519744561
Fix commita019509362c6 (chromium/src) +106/-6
CISA KEVNot listed
CreditedGoogle
Disclosed2026-07-29

Changed Functions

FunctionChangeNotes
if
chrome/browser/ui/global_media_controls/presentation_request_notification_item.cc
modified

Files Changed

  • chrome/browser/ui/global_media_controls/presentation_request_notification_item.cc
  • chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
  • chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
From a019509362c68d8ab8669fe28013822301cb73a5 Mon Sep 17 00:00:00 2001
From: Muyao Xu <muyaoxu@google.com>
Date: Wed, 10 Jun 2026 16:07:33 -0700
Subject: [PATCH] [MediaRouter] Only use Mediasession metadata for same-origin requests

Onl use the tab's MediaSession metadata for the
PresentationRequestNotificationItem when they are from the same
origin.

Bug: 519744561
Change-Id: Ia95f35f2226597e6f81bfe825be53f67ac78d6f9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7916088
Reviewed-by: Jordan Bayles <jophba@chromium.org>
Commit-Queue: Muyao Xu <muyaoxu@google.com>
Cr-Commit-Position: refs/heads/main@{#1644954}
---

diff --git a/chrome/browser/ui/global_media_controls/presentation_request_notification_item.cc b/chrome/browser/ui/global_media_controls/presentation_request_notification_item.cc
index d88b9ed..79aa20f0 100644
--- a/chrome/browser/ui/global_media_controls/presentation_request_notification_item.cc
+++ b/chrome/browser/ui/global_media_controls/presentation_request_notification_item.cc
@@ -11,6 +11,7 @@
 #include "components/global_media_controls/public/media_item_manager.h"
 #include "components/media_message_center/media_notification_util.h"
 #include "content/public/browser/media_session.h"
+#include "content/public/browser/render_frame_host.h"
 #include "services/media_session/public/cpp/media_image_manager.h"
 #include "services/media_session/public/cpp/media_metadata.h"
 #include "ui/gfx/image/image_skia.h"
@@ -155,9 +156,10 @@
   if (!provider_->is_bound()) {
     return;
   }
-  // If we have metadata from the media session, use that.
-  media_session::MediaMetadata data =
-      metadata_.value_or(media_session::MediaMetadata{});
+  media_session::MediaMetadata data;
+  if (metadata_.has_value() && ShouldShowMediaSessionMetadata()) {
+    data = *metadata_;
+  }
 
   if (media_message_center::IsOriginGoodForDisplay(request_.frame_origin)) {
     // `request_` has more accurate origin info than `metadata_` e.g. when the
@@ -179,12 +181,17 @@
   if (!provider_->is_bound()) {
     return;
   }
-  (*provider_)->OnArtworkImageChanged(artwork_image_);
-  if (!favicon_image_.isNull()) {
+
+  const bool should_show_metadata = ShouldShowMediaSessionMetadata();
+  (*provider_)
+      ->OnArtworkImageChanged(should_show_metadata ? artwork_image_
+                                                   : gfx::ImageSkia());
+
+  if (should_show_metadata && !favicon_image_.isNull()) {
     (*provider_)->OnFaviconImageChanged(favicon_image_);
     return;
   }
-  // Otherwise, get one ourselves.
+
   auto* web_contents = GetWebContentsFromPresentationRequest(request_);
   if (web_contents) {
     favicon::FaviconDriver* favicon_driver =
@@ -209,3 +216,21 @@
   favicon_image_ = GetCorrectColorTypeImage(bitmap).value_or(gfx::ImageSkia());
   UpdatePickerWithImages();
 }
+
+bool PresentationRequestNotificationItem::ShouldShowMediaSessionMetadata()
+    const {
+  auto* web_contents = GetWebContentsFromPresentationRequest(request_);
+  if (!web_contents) {
+    return false;
+  }
+  auto* media_session = GetMediaSession(web_contents);
+  if (!media_session) {
+    return false;
+  }
+  content::RenderFrameHost* routed_frame = media_session->GetRoutedFrame();
+  if (!routed_frame) {
+    return true;
+  }
+  return routed_frame->GetLastCommittedOrigin().IsSameOriginWith(
+      request_.frame_origin);
+}
diff --git a/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h b/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
index e32f83a2..7210879 100644
--- a/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
+++ b/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
@@ -86,6 +86,10 @@
   void OnArtworkBitmap(const SkBitmap& bitmap);
   void OnFaviconBitmap(const SkBitmap& bitmap);
 
+  // Returns true if the origin of the active MediaSession's routed frame is the
+  // same as the origin of the frame that initiated the presentation request.
+  bool ShouldShowMediaSessionMetadata() const;
+
   // True if the item is created from a default PresentationRequest, which means
   // |context_| is set to nullptr in the constructor.
   const bool is_default_presentation_request_;
diff --git a/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc b/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
index 8d532a2..027e83d 100644
--- a/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
+++ b/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
@@ -8,7 +8,10 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/global_media_controls/public/test/mock_device_service.h"
 #include "components/media_router/common/mojom/media_router.mojom.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/mock_media_session.h"
+#include "content/public/test/navigation_simulator.h"
+#include "content/public/test/test_renderer_host.h"
 #include "services/media_session/public/cpp/media_image.h"
 #include "services/media_session/public/mojom/media_session.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -21,6 +24,7 @@
  protected:
   void SetUp() override {
     ChromeRenderViewHostTestHarness::SetUp();
+    NavigateAndCommit(GURL("https://example.com"));
     PresentationRequestNotificationItem::SetMediaSessionForTest(
         &media_session_);
 
@@ -79,3 +83,70 @@
   item_->MediaSessionImagesChanged(
       {{media_session::mojom::MediaSessionImageType::kArtwork, {image}}});
 }
+
+TEST_F(PresentationRequestNotificationItemTest,
+       MediaSessionMetadataChanged_RoutedFrameOriginMatch) {
+  EXPECT_CALL(media_session_, GetRoutedFrame())
+      .WillRepeatedly(testing::Return(main_rfh()));
+
+  media_session::MediaMetadata metadata;
+  metadata.source_title = u"some-other-domain.com";
+  metadata.artist = u"My title";
+
+  EXPECT_CALL(*provider_, OnMetadataChanged)
+      .WillOnce([metadata](const media_session::MediaMetadata& metadata_arg) {
+        EXPECT_EQ(u"example.com", metadata_arg.source_title);
+        EXPECT_EQ(metadata.artist, metadata_arg.artist);
+      });
+  item_->MediaSessionMetadataChanged(metadata);
+}
+
+TEST_F(PresentationRequestNotificationItemTest,
+       MediaSessionMetadataChanged_RoutedFrameOriginMismatch) {
+  content::RenderFrameHost* child_rfh =
+      content::RenderFrameHostTester::For(main_rfh())
+          ->AppendChild("child_frame");
+  child_rfh = content::NavigationSimulator::NavigateAndCommitFromDocument(
+      GURL("https://other.com"), child_rfh);
+
+  EXPECT_CALL(media_session_, GetRoutedFrame())
+      .WillRepeatedly(testing::Return(child_rfh));
+
+  media_session::MediaMetadata metadata;
+  metadata.source_title = u"some-other-domain.com";
+  metadata.artist = u"My title";
+
+  EXPECT_CALL(*provider_, OnMetadataChanged)
+      .WillOnce([this](const media_session::MediaMetadata& metadata_arg) {
+        EXPECT_EQ(u"example.com", metadata_arg.source_title);
+        EXPECT_TRUE(metadata_arg.title.empty());
+        EXPECT_EQ(web_contents()->GetTitle(), metadata_arg.artist);
+      });
+  item_->MediaSessionMetadataChanged(metadata);
+}
+
+TEST_F(PresentationRequestNotificationItemTest,
+       MediaSessionImagesChanged_RoutedFrameOriginMismatch) {
+  content::RenderFrameHost* child_rfh =
+      content::RenderFrameHostTester::For(main_rfh())
+          ->AppendChild("child_frame");
+  child_rfh = content::NavigationSimulator::NavigateAndCommitFromDocument(
+      GURL("https://other.com"), child_rfh);
+
+  EXPECT_CALL(media_session_, GetRoutedFrame())
+      .WillRepeatedly(testing::Return(child_rfh));
+
+  media_session::MediaImage image;
+  image.src = GURL{"https://example.com"};
+  image.sizes = {{100, 100}};
+
+  EXPECT_CALL(*provider_, OnArtworkImageChanged)
+      .WillOnce(
+          [](const gfx::ImageSkia& image) { EXPECT_TRUE(image.isNull()); });
+  EXPECT_CALL(*provider_, OnFaviconImageChanged)
+      .WillOnce(
+          [](const gfx::ImageSkia& image) { EXPECT_TRUE(image.isNull()); });
+
+  item_->MediaSessionImagesChanged(
+      {{media_session::mojom::MediaSessionImageType::kArtwork, {image}}});
+}
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc b/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
index 8d532a2..027e83d 100644
--- a/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
+++ b/chrome/browser/ui/global_media_controls/presentation_request_notification_item_unittest.cc
@@ -8,7 +8,10 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/global_media_controls/public/test/mock_device_service.h"
 #include "components/media_router/common/mojom/media_router.mojom.h"
+#include "content/public/browser/web_contents.h"
 #include "content/public/test/mock_media_session.h"
+#include "content/public/test/navigation_simulator.h"
+#include "content/public/test/test_renderer_host.h"
 #include "services/media_session/public/cpp/media_image.h"
 #include "services/media_session/public/mojom/media_session.mojom.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -21,6 +24,7 @@
  protected:
   void SetUp() override {
     ChromeRenderViewHostTestHarness::SetUp();
+    NavigateAndCommit(GURL("https://example.com"));
     PresentationRequestNotificationItem::SetMediaSessionForTest(
         &media_session_);
 
@@ -79,3 +83,70 @@
   item_->MediaSessionImagesChanged(
       {{media_session::mojom::MediaSessionImageType::kArtwork, {image}}});
 }
+
+TEST_F(PresentationRequestNotificationItemTest,
+       MediaSessionMetadataChanged_RoutedFrameOriginMatch) {
+  EXPECT_CALL(media_session_, GetRoutedFrame())
+      .WillRepeatedly(testing::Return(main_rfh()));
+
+  media_session::MediaMetadata metadata;
+  metadata.source_title = u"some-other-domain.com";
+  metadata.artist = u"My title";
+
+  EXPECT_CALL(*provider_, OnMetadataChanged)
+      .WillOnce([metadata](const media_session::MediaMetadata& metadata_arg) {
+        EXPECT_EQ(u"example.com", metadata_arg.source_title);
+        EXPECT_EQ(metadata.artist, metadata_arg.artist);
+      });
+  item_->MediaSessionMetadataChanged(metadata);
+}
+
+TEST_F(PresentationRequestNotificationItemTest,
+       MediaSessionMetadataChanged_RoutedFrameOriginMismatch) {
+  content::RenderFrameHost* child_rfh =
+      content::RenderFrameHostTester::For(main_rfh())
+          ->AppendChild("child_frame");
+  child_rfh = content::NavigationSimulator::NavigateAndCommitFromDocument(
+      GURL("https://other.com"), child_rfh);
+
+  EXPECT_CALL(media_session_, GetRoutedFrame())
+      .WillRepeatedly(testing::Return(child_rfh));
+
+  media_session::MediaMetadata metadata;
+  metadata.source_title = u"some-other-domain.com";
+  metadata.artist = u"My title";
+
+  EXPECT_CALL(*provider_, OnMetadataChanged)
+      .WillOnce([this](const media_session::MediaMetadata& metadata_arg) {
+        EXPECT_EQ(u"example.com", metadata_arg.source_title);
+        EXPECT_TRUE(metadata_arg.title.empty());
+        EXPECT_EQ(web_contents()->GetTitle(), metadata_arg.artist);
+      });
+  item_->MediaSessionMetadataChanged(metadata);
+}
+
+TEST_F(PresentationRequestNotificationItemTest,
+       MediaSessionImagesChanged_RoutedFrameOriginMismatch) {
+  content::RenderFrameHost* child_rfh =
+      content::RenderFrameHostTester::For(main_rfh())
+          ->AppendChild("child_frame");
+  child_rfh = content::NavigationSimulator::NavigateAndCommitFromDocument(
+      GURL("https://other.com"), child_rfh);
+
+  EXPECT_CALL(media_session_, GetRoutedFrame())
+      .WillRepeatedly(testing::Return(child_rfh));
+
+  media_session::MediaImage image;
+  image.src = GURL{"https://example.com"};
+  image.sizes = {{100, 100}};
+
+  EXPECT_CALL(*provider_, OnArtworkImageChanged)
+      .WillOnce(
+          [](const gfx::ImageSkia& image) { EXPECT_TRUE(image.isNull()); });
+  EXPECT_CALL(*provider_, OnFaviconImageChanged)
+      .WillOnce(
+          [](const gfx::ImageSkia& image) { EXPECT_TRUE(image.isNull()); });
+
+  item_->MediaSessionImagesChanged(
+      {{media_session::mojom::MediaSessionImageType::kArtwork, {image}}});
+}
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.