Repository: electron/electron
Pull request: fix: use requesting frame origin in permission helper and device choosers

Backport of #50052

See that PR for details.


Notes: Fixed an issue where permission and device-chooser handlers received the top-level page origin instead of the requesting subframe's origin.

Changed files:
filename: shell/browser/hid/hid_chooser_controller.cc
patch: @@ -88,13 +88,9 @@ HidChooserController::HidChooserController(
       exclusion_filters_(std::move(exclusion_filters)),
       callback_(std::move(callback)),
       initiator_document_(render_frame_host->GetWeakDocumentPtr()),
-      origin_(content::WebContents::FromRenderFrameHost(render_frame_host)
-                  ->GetPrimaryMainFrame()
-                  ->GetLastCommittedOrigin()),
+      origin_(render_frame_host->GetLastCommittedOrigin()),
       hid_delegate_(hid_delegate),
       render_frame_host_id_(render_frame_host->GetGlobalId()) {
-  // The use above of GetMainFrame is safe as content::HidService instances are
-  // not created for fenced frames.
   DCHECK(!render_frame_host->IsNestedWithinFencedFrame());
 
   chooser_context_ = HidChooserContextFactory::GetForBrowserContext(

filename: shell/browser/serial/electron_serial_delegate.cc
patch: @@ -52,25 +52,21 @@ bool ElectronSerialDelegate::CanRequestPortPermission(
   auto* permission_helper =
       WebContentsPermissionHelper::FromWebContents(web_contents);
   return permission_helper->CheckSerialAccessPermission(
-      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin());
+      frame->GetLastCommittedOrigin());
 }
 
 bool ElectronSerialDelegate::HasPortPermission(
     content::RenderFrameHost* frame,
     const device::mojom::SerialPortInfo& port) {
-  auto* web_contents = content::WebContents::FromRenderFrameHost(frame);
   return GetChooserContext(frame)->HasPortPermission(
-      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(), port,
-      frame);
+      frame->GetLastCommittedOrigin(), port, frame);
 }
 
 void ElectronSerialDelegate::RevokePortPermissionWebInitiated(
     content::RenderFrameHost* frame,
     const base::UnguessableToken& token) {
-  auto* web_contents = content::WebContents::FromRenderFrameHost(frame);
   return GetChooserContext(frame)->RevokePortPermissionWebInitiated(
-      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin(), token,
-      frame);
+      frame->GetLastCommittedOrigin(), token, frame);
 }
 
 const device::mojom::SerialPortInfo* ElectronSerialDelegate::GetPortInfo(

filename: shell/browser/serial/serial_chooser_controller.cc
patch: @@ -125,7 +125,7 @@ SerialChooserController::SerialChooserController(
           std::move(allowed_bluetooth_service_class_ids)),
       callback_(std::move(callback)),
       initiator_document_(render_frame_host->GetWeakDocumentPtr()) {
-  origin_ = web_contents_->GetPrimaryMainFrame()->GetLastCommittedOrigin();
+  origin_ = render_frame_host->GetLastCommittedOrigin();
 
   chooser_context_ = SerialChooserContextFactory::GetForBrowserContext(
                          web_contents_->GetBrowserContext())

filename: shell/browser/usb/usb_chooser_controller.cc
patch: @@ -43,7 +43,7 @@ UsbChooserController::UsbChooserController(
     : WebContentsObserver(web_contents),
       options_(std::move(options)),
       callback_(std::move(callback)),
-      origin_(render_frame_host->GetMainFrame()->GetLastCommittedOrigin()),
+      origin_(render_frame_host->GetLastCommittedOrigin()),
       usb_delegate_(usb_delegate),
       render_frame_host_id_(render_frame_host->GetGlobalId()) {
   chooser_context_ = UsbChooserContextFactory::GetForBrowserContext(

filename: shell/browser/web_contents_permission_helper.cc
patch: @@ -219,7 +219,7 @@ void WebContentsPermissionHelper::RequestPermission(
     base::Value::Dict details) {
   auto* permission_manager = static_cast<ElectronPermissionManager*>(
       web_contents_->GetBrowserContext()->GetPermissionControllerDelegate());
-  auto origin = web_contents_->GetLastCommittedURL();
+  auto origin = requesting_frame->GetLastCommittedOrigin().GetURL();
   permission_manager->RequestPermissionWithDetails(
       content::PermissionDescriptorUtil::
           CreatePermissionDescriptorForPermissionType(permission),