feat: route deprecated sync clipboard read through permission checks (#45471)

* feat: route deprecated clipboard commands through permission checks

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* docs: address review feedback

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* fix: enable checks for child windows

Co-authored-by: deepak1556 <hop2deep@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
This commit is contained in:
trop[bot] 2025-02-05 14:10:43 -05:00 committed by GitHub
parent 51170c3652
commit 46c9ed61da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 441 additions and 35 deletions

View file

@ -13,13 +13,13 @@
#include "base/no_destructor.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h" // nogncheck
#include "content/browser/service_worker/service_worker_version.h" // nogncheck
#include "electron/shell/common/api/api.mojom.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "shell/browser/api/message_port.h"
#include "shell/browser/browser.h"
#include "shell/browser/javascript_environment.h"
#include "shell/common/api/api.mojom.h"
#include "shell/common/gin_converters/blink_converter.h"
#include "shell/common/gin_converters/gurl_converter.h"
#include "shell/common/gin_converters/value_converter.h"

View file

@ -70,7 +70,6 @@
#include "content/public/common/webplugininfo.h"
#include "electron/buildflags/buildflags.h"
#include "electron/mas.h"
#include "electron/shell/common/api/api.mojom.h"
#include "gin/arguments.h"
#include "gin/data_object_builder.h"
#include "gin/handle.h"
@ -110,6 +109,7 @@
#include "shell/browser/web_contents_zoom_controller.h"
#include "shell/browser/web_view_guest_delegate.h"
#include "shell/browser/web_view_manager.h"
#include "shell/common/api/api.mojom.h"
#include "shell/common/api/electron_api_native_image.h"
#include "shell/common/api/electron_bindings.h"
#include "shell/common/color_util.h"

View file

@ -31,7 +31,6 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "electron/buildflags/buildflags.h"
#include "electron/shell/common/api/api.mojom.h"
#include "gin/handle.h"
#include "gin/wrappable.h"
#include "printing/buildflags/buildflags.h"
@ -43,9 +42,11 @@
#include "shell/browser/preload_script.h"
#include "shell/browser/ui/inspectable_web_contents_delegate.h"
#include "shell/browser/ui/inspectable_web_contents_view_delegate.h"
#include "shell/common/api/api.mojom.h"
#include "shell/common/gin_helper/cleaned_up_at_exit.h"
#include "shell/common/gin_helper/constructible.h"
#include "shell/common/gin_helper/pinnable.h"
#include "shell/common/web_contents_utility.mojom.h"
#include "ui/base/models/image_model.h"
#if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)

View file

@ -17,13 +17,13 @@
#include "content/public/browser/frame_tree_node_id.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/isolated_world_ids.h"
#include "electron/shell/common/api/api.mojom.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "shell/browser/api/message_port.h"
#include "shell/browser/browser.h"
#include "shell/browser/javascript_environment.h"
#include "shell/common/api/api.mojom.h"
#include "shell/common/gin_converters/blink_converter.h"
#include "shell/common/gin_converters/frame_converter.h"
#include "shell/common/gin_converters/gurl_converter.h"

View file

@ -10,9 +10,9 @@
#include "base/memory/weak_ptr.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "electron/shell/common/api/api.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/common/api/api.mojom.h"
namespace content {
class RenderFrameHost;

View file

@ -53,7 +53,6 @@
#include "crypto/crypto_buildflags.h"
#include "electron/buildflags/buildflags.h"
#include "electron/fuses.h"
#include "electron/shell/common/api/api.mojom.h"
#include "extensions/browser/extension_navigation_ui_data.h"
#include "extensions/common/extension_id.h"
#include "mojo/public/cpp/bindings/binder_map.h"
@ -117,6 +116,7 @@
#include "shell/common/platform_util.h"
#include "shell/common/plugin.mojom.h"
#include "shell/common/thread_restrictions.h"
#include "shell/common/web_contents_utility.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"

View file

@ -298,8 +298,13 @@ bool ElectronPermissionManager::CheckPermissionWithDetails(
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
base::Value::Dict details) const {
if (check_handler_.is_null())
return true;
if (check_handler_.is_null()) {
if (permission == blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ) {
return false;
} else {
return true;
}
}
auto* web_contents =
render_frame_host

View file

@ -6,15 +6,19 @@
#include <utility>
#include "content/public/browser/browser_context.h"
#include "content/public/browser/permission_controller.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "shell/browser/web_contents_permission_helper.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
namespace electron {
ElectronWebContentsUtilityHandlerImpl::ElectronWebContentsUtilityHandlerImpl(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronWebContentsUtility> receiver)
: render_frame_host_id_(frame_host->GetGlobalId()) {
: render_frame_host_token_(frame_host->GetGlobalFrameToken()) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(frame_host);
DCHECK(web_contents);
@ -28,8 +32,11 @@ ElectronWebContentsUtilityHandlerImpl::ElectronWebContentsUtilityHandlerImpl(
ElectronWebContentsUtilityHandlerImpl::
~ElectronWebContentsUtilityHandlerImpl() = default;
void ElectronWebContentsUtilityHandlerImpl::WebContentsDestroyed() {
delete this;
void ElectronWebContentsUtilityHandlerImpl::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
if (render_frame_host->GetGlobalFrameToken() == render_frame_host_token_) {
delete this;
}
}
void ElectronWebContentsUtilityHandlerImpl::OnConnectionError() {
@ -59,9 +66,42 @@ void ElectronWebContentsUtilityHandlerImpl::DoGetZoomLevel(
}
}
void ElectronWebContentsUtilityHandlerImpl::CanAccessClipboardDeprecated(
mojom::PermissionName name,
const blink::LocalFrameToken& frame_token,
CanAccessClipboardDeprecatedCallback callback) {
if (render_frame_host_token_.frame_token == frame_token) {
// Paste requires either (1) user activation, ...
if (web_contents()->HasRecentInteraction()) {
std::move(callback).Run(blink::mojom::PermissionStatus::GRANTED);
return;
}
// (2) granted permission, ...
content::RenderFrameHost* render_frame_host = GetRenderFrameHost();
content::BrowserContext* browser_context =
render_frame_host->GetBrowserContext();
content::PermissionController* permission_controller =
browser_context->GetPermissionController();
blink::PermissionType permission;
if (name == mojom::PermissionName::DEPRECATED_SYNC_CLIPBOARD_READ) {
permission = blink::PermissionType::DEPRECATED_SYNC_CLIPBOARD_READ;
} else {
std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
return;
}
blink::mojom::PermissionStatus status =
permission_controller->GetPermissionStatusForCurrentDocument(
permission, render_frame_host);
std::move(callback).Run(status);
} else {
std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
}
}
content::RenderFrameHost*
ElectronWebContentsUtilityHandlerImpl::GetRenderFrameHost() {
return content::RenderFrameHost::FromID(render_frame_host_id_);
return content::RenderFrameHost::FromFrameToken(render_frame_host_token_);
}
// static

View file

@ -10,7 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/web_contents_observer.h"
#include "electron/shell/common/api/api.mojom.h"
#include "electron/shell/common/web_contents_utility.mojom.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "shell/browser/api/electron_api_web_contents.h"
@ -43,6 +43,10 @@ class ElectronWebContentsUtilityHandlerImpl
void OnFirstNonEmptyLayout() override;
void SetTemporaryZoomLevel(double level) override;
void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;
void CanAccessClipboardDeprecated(
mojom::PermissionName name,
const blink::LocalFrameToken& frame_token,
CanAccessClipboardDeprecatedCallback callback) override;
base::WeakPtr<ElectronWebContentsUtilityHandlerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
@ -52,13 +56,13 @@ class ElectronWebContentsUtilityHandlerImpl
~ElectronWebContentsUtilityHandlerImpl() override;
// content::WebContentsObserver:
void WebContentsDestroyed() override;
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
void OnConnectionError();
content::RenderFrameHost* GetRenderFrameHost();
content::GlobalRenderFrameHostId render_frame_host_id_;
content::GlobalRenderFrameHostToken render_frame_host_token_;
mojo::AssociatedReceiver<mojom::ElectronWebContentsUtility> receiver_{this};

View file

@ -32,7 +32,7 @@ class WebContentsPermissionHelper
HID,
USB,
KEYBOARD_LOCK,
FILE_SYSTEM
FILE_SYSTEM,
};
// Asynchronous Requests

View file

@ -148,6 +148,7 @@ void WebContentsPreferences::Clear() {
blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed;
preload_path_ = std::nullopt;
v8_cache_options_ = blink::mojom::V8CacheOptions::kDefault;
deprecated_paste_enabled_ = false;
#if BUILDFLAG(IS_MAC)
scroll_bounce_ = false;
@ -245,6 +246,9 @@ void WebContentsPreferences::SetFromDictionary(
web_preferences.Get("v8CacheOptions", &v8_cache_options_);
web_preferences.Get(options::kEnableDeprecatedPaste,
&deprecated_paste_enabled_);
#if BUILDFLAG(IS_MAC)
web_preferences.Get(options::kScrollBounce, &scroll_bounce_);
#endif
@ -472,6 +476,8 @@ void WebContentsPreferences::OverrideWebkitPrefs(
prefs->webview_tag = webview_tag_;
prefs->v8_cache_options = v8_cache_options_;
prefs->dom_paste_enabled = deprecated_paste_enabled_;
}
WEB_CONTENTS_USER_DATA_KEY_IMPL(WebContentsPreferences);

View file

@ -133,6 +133,7 @@ class WebContentsPreferences
blink::mojom::ImageAnimationPolicy image_animation_policy_;
std::optional<base::FilePath> preload_path_;
blink::mojom::V8CacheOptions v8_cache_options_;
bool deprecated_paste_enabled_ = false;
#if BUILDFLAG(IS_MAC)
bool scroll_bounce_;