diff --git a/chrome/browser/ui/global_media_controls/media_notification_service.cc b/chrome/browser/ui/global_media_controls/media_notification_service.cc --- a/chrome/browser/ui/global_media_controls/media_notification_service.cc +++ b/chrome/browser/ui/global_media_controls/media_notification_service.cc @@ -506,13 +506,21 @@ void MediaNotificationService::SetDevicePickerProvider( std::unique_ptr MediaNotificationService::CreateCastDialogControllerForSession( const std::string& id) { auto* web_contents = content::MediaSession::GetWebContentsFromRequestId(id); if (!web_contents) { return nullptr; } - if (context_) { - return media_router::MediaRouterUI::CreateWithStartPresentationContext( - web_contents, std::move(context_)); + if (context_) { + // Only consume the pending StartPresentationContext for the session that + // actually requested it. On ChromeOS the Ash media tray builds device + // selectors for every active media item, and without this check an + // unrelated (e.g. actively-playing victim) tab's selector could consume + // the attacker's presentation context. + if (web_contents == content::WebContents::FromRenderFrameHost( + content::RenderFrameHost::FromID( + context_->presentation_request().render_frame_host_id))) { + return media_router::MediaRouterUI::CreateWithStartPresentationContext( + web_contents, std::move(context_)); + } } auto remote_playback_metadata =