Skip to content

Commit

Permalink
fix: ensure ElectronBrowser mojo service is only bound to appropriate…
Browse files Browse the repository at this point in the history
… render frames (#33367)

* Make ElectronBrowser mojo interface frame associated. (#32815)

Co-authored-by: Marek Haranczyk <marek@openfin.co>

* fix: ensure ElectronBrowser mojo service is only bound to appropriate render frames (#33323) (#33350)

* fix: ensure ElectronBrowser mojo service is only bound to authorized render frames

Notes: no-notes

* refactor: extract electron API IPC to its own mojo interface

* fix: just check main frame not primary main frame

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Marek Haranczyk <marek@openfin.co>
  • Loading branch information
3 people committed May 11, 2022
1 parent a203965 commit d5dd3fb
Show file tree
Hide file tree
Showing 16 changed files with 399 additions and 240 deletions.
6 changes: 4 additions & 2 deletions filenames.gni
Expand Up @@ -352,6 +352,8 @@ filenames = {
"shell/browser/child_web_contents_tracker.h",
"shell/browser/cookie_change_notifier.cc",
"shell/browser/cookie_change_notifier.h",
"shell/browser/electron_api_ipc_handler_impl.cc",
"shell/browser/electron_api_ipc_handler_impl.h",
"shell/browser/electron_autofill_driver.cc",
"shell/browser/electron_autofill_driver.h",
"shell/browser/electron_autofill_driver_factory.cc",
Expand All @@ -360,8 +362,6 @@ filenames = {
"shell/browser/electron_browser_client.h",
"shell/browser/electron_browser_context.cc",
"shell/browser/electron_browser_context.h",
"shell/browser/electron_browser_handler_impl.cc",
"shell/browser/electron_browser_handler_impl.h",
"shell/browser/electron_browser_main_parts.cc",
"shell/browser/electron_browser_main_parts.h",
"shell/browser/electron_download_manager_delegate.cc",
Expand All @@ -378,6 +378,8 @@ filenames = {
"shell/browser/electron_quota_permission_context.h",
"shell/browser/electron_speech_recognition_manager_delegate.cc",
"shell/browser/electron_speech_recognition_manager_delegate.h",
"shell/browser/electron_web_contents_utility_handler_impl.cc",
"shell/browser/electron_web_contents_utility_handler_impl.h",
"shell/browser/electron_web_ui_controller_factory.cc",
"shell/browser/electron_web_ui_controller_factory.h",
"shell/browser/event_emitter_mixin.cc",
Expand Down
13 changes: 7 additions & 6 deletions shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -1661,15 +1661,15 @@ void WebContents::Message(bool internal,
// webContents.emit('-ipc-message', new Event(), internal, channel,
// arguments);
EmitWithSender("-ipc-message", render_frame_host,
electron::mojom::ElectronBrowser::InvokeCallback(), internal,
electron::mojom::ElectronApiIPC::InvokeCallback(), internal,
channel, std::move(arguments));
}

void WebContents::Invoke(
bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::InvokeCallback callback,
electron::mojom::ElectronApiIPC::InvokeCallback callback,
content::RenderFrameHost* render_frame_host) {
TRACE_EVENT1("electron", "WebContents::Invoke", "channel", channel);
// webContents.emit('-ipc-invoke', new Event(), internal, channel, arguments);
Expand All @@ -1695,15 +1695,15 @@ void WebContents::ReceivePostMessage(
v8::Local<v8::Value> message_value =
electron::DeserializeV8Value(isolate, message);
EmitWithSender("-ipc-ports", render_frame_host,
electron::mojom::ElectronBrowser::InvokeCallback(), false,
electron::mojom::ElectronApiIPC::InvokeCallback(), false,
channel, message_value, std::move(wrapped_ports));
}

void WebContents::MessageSync(
bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::MessageSyncCallback callback,
electron::mojom::ElectronApiIPC::MessageSyncCallback callback,
content::RenderFrameHost* render_frame_host) {
TRACE_EVENT1("electron", "WebContents::MessageSync", "channel", channel);
// webContents.emit('-ipc-message-sync', new Event(sender, message), internal,
Expand Down Expand Up @@ -1741,7 +1741,7 @@ void WebContents::MessageHost(const std::string& channel,
TRACE_EVENT1("electron", "WebContents::MessageHost", "channel", channel);
// webContents.emit('ipc-message-host', new Event(), channel, args);
EmitWithSender("ipc-message-host", render_frame_host,
electron::mojom::ElectronBrowser::InvokeCallback(), channel,
electron::mojom::ElectronApiIPC::InvokeCallback(), channel,
std::move(arguments));
}

Expand Down Expand Up @@ -3154,7 +3154,8 @@ void WebContents::SetTemporaryZoomLevel(double level) {
}

void WebContents::DoGetZoomLevel(
electron::mojom::ElectronBrowser::DoGetZoomLevelCallback callback) {
electron::mojom::ElectronWebContentsUtility::DoGetZoomLevelCallback
callback) {
std::move(callback).Run(GetZoomLevel());
}

Expand Down
16 changes: 10 additions & 6 deletions shell/browser/api/electron_api_web_contents.h
Expand Up @@ -352,7 +352,7 @@ class WebContents : public gin::Wrappable<WebContents>,
template <typename... Args>
bool EmitWithSender(base::StringPiece name,
content::RenderFrameHost* sender,
electron::mojom::ElectronBrowser::InvokeCallback callback,
electron::mojom::ElectronApiIPC::InvokeCallback callback,
Args&&... args) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
Expand Down Expand Up @@ -396,36 +396,40 @@ class WebContents : public gin::Wrappable<WebContents>,
fullscreen_frame_ = rfh;
}

// mojom::ElectronBrowser
// mojom::ElectronApiIPC
void Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
content::RenderFrameHost* render_frame_host);
void Invoke(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::InvokeCallback callback,
electron::mojom::ElectronApiIPC::InvokeCallback callback,
content::RenderFrameHost* render_frame_host);
void OnFirstNonEmptyLayout(content::RenderFrameHost* render_frame_host);
void ReceivePostMessage(const std::string& channel,
blink::TransferableMessage message,
content::RenderFrameHost* render_frame_host);
void MessageSync(
bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
electron::mojom::ElectronBrowser::MessageSyncCallback callback,
electron::mojom::ElectronApiIPC::MessageSyncCallback callback,
content::RenderFrameHost* render_frame_host);
void MessageTo(int32_t web_contents_id,
const std::string& channel,
blink::CloneableMessage arguments);
void MessageHost(const std::string& channel,
blink::CloneableMessage arguments,
content::RenderFrameHost* render_frame_host);

// mojom::ElectronWebContentsUtility
void OnFirstNonEmptyLayout(content::RenderFrameHost* render_frame_host);
void UpdateDraggableRegions(std::vector<mojom::DraggableRegionPtr> regions);
void SetTemporaryZoomLevel(double level);
void DoGetZoomLevel(
electron::mojom::ElectronBrowser::DoGetZoomLevelCallback callback);
electron::mojom::ElectronWebContentsUtility::DoGetZoomLevelCallback
callback);

void SetImageAnimationPolicy(const std::string& new_policy);

// Grants |origin| access to |device|.
Expand Down
2 changes: 1 addition & 1 deletion shell/browser/api/event.h
Expand Up @@ -13,7 +13,7 @@ namespace gin_helper {

class Event : public gin::Wrappable<Event> {
public:
using InvokeCallback = electron::mojom::ElectronBrowser::InvokeCallback;
using InvokeCallback = electron::mojom::ElectronApiIPC::InvokeCallback;

static gin::WrapperInfo kWrapperInfo;

Expand Down
108 changes: 108 additions & 0 deletions shell/browser/electron_api_ipc_handler_impl.cc
@@ -0,0 +1,108 @@
// Copyright (c) 2022 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "shell/browser/electron_api_ipc_handler_impl.h"

#include <utility>

#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"

namespace electron {
ElectronApiIPCHandlerImpl::ElectronApiIPCHandlerImpl(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver)
: render_process_id_(frame_host->GetProcess()->GetID()),
render_frame_id_(frame_host->GetRoutingID()) {
content::WebContents* web_contents =
content::WebContents::FromRenderFrameHost(frame_host);
DCHECK(web_contents);
content::WebContentsObserver::Observe(web_contents);

receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(base::BindOnce(
&ElectronApiIPCHandlerImpl::OnConnectionError, GetWeakPtr()));
}

ElectronApiIPCHandlerImpl::~ElectronApiIPCHandlerImpl() = default;

void ElectronApiIPCHandlerImpl::WebContentsDestroyed() {
delete this;
}

void ElectronApiIPCHandlerImpl::OnConnectionError() {
delete this;
}

void ElectronApiIPCHandlerImpl::Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->Message(internal, channel, std::move(arguments),
GetRenderFrameHost());
}
}
void ElectronApiIPCHandlerImpl::Invoke(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
InvokeCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->Invoke(internal, channel, std::move(arguments),
std::move(callback), GetRenderFrameHost());
}
}

void ElectronApiIPCHandlerImpl::ReceivePostMessage(
const std::string& channel,
blink::TransferableMessage message) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->ReceivePostMessage(channel, std::move(message),
GetRenderFrameHost());
}
}

void ElectronApiIPCHandlerImpl::MessageSync(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
MessageSyncCallback callback) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageSync(internal, channel, std::move(arguments),
std::move(callback), GetRenderFrameHost());
}
}

void ElectronApiIPCHandlerImpl::MessageTo(int32_t web_contents_id,
const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageTo(web_contents_id, channel, std::move(arguments));
}
}

void ElectronApiIPCHandlerImpl::MessageHost(const std::string& channel,
blink::CloneableMessage arguments) {
api::WebContents* api_web_contents = api::WebContents::From(web_contents());
if (api_web_contents) {
api_web_contents->MessageHost(channel, std::move(arguments),
GetRenderFrameHost());
}
}

content::RenderFrameHost* ElectronApiIPCHandlerImpl::GetRenderFrameHost() {
return content::RenderFrameHost::FromID(render_process_id_, render_frame_id_);
}

// static
void ElectronApiIPCHandlerImpl::Create(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver) {
new ElectronApiIPCHandlerImpl(frame_host, std::move(receiver));
}
} // namespace electron
@@ -1,9 +1,9 @@
// Copyright (c) 2019 Slack Technologies, Inc.
// Copyright (c) 2022 Slack Technologies, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#ifndef SHELL_BROWSER_ELECTRON_BROWSER_HANDLER_IMPL_H_
#define SHELL_BROWSER_ELECTRON_BROWSER_HANDLER_IMPL_H_
#ifndef SHELL_BROWSER_ELECTRON_API_IPC_HANDLER_IMPL_H_
#define SHELL_BROWSER_ELECTRON_API_IPC_HANDLER_IMPL_H_

#include <string>
#include <vector>
Expand All @@ -21,25 +21,25 @@ class RenderFrameHost;
}

namespace electron {
class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
public content::WebContentsObserver {
class ElectronApiIPCHandlerImpl : public mojom::ElectronApiIPC,
public content::WebContentsObserver {
public:
explicit ElectronBrowserHandlerImpl(
explicit ElectronApiIPCHandlerImpl(
content::RenderFrameHost* render_frame_host,
mojo::PendingReceiver<mojom::ElectronBrowser> receiver);
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver);

static void Create(content::RenderFrameHost* frame_host,
mojo::PendingReceiver<mojom::ElectronBrowser> receiver);
static void Create(
content::RenderFrameHost* frame_host,
mojo::PendingAssociatedReceiver<mojom::ElectronApiIPC> receiver);

// mojom::ElectronBrowser:
// mojom::ElectronApiIPC:
void Message(bool internal,
const std::string& channel,
blink::CloneableMessage arguments) override;
void Invoke(bool internal,
const std::string& channel,
blink::CloneableMessage arguments,
InvokeCallback callback) override;
void OnFirstNonEmptyLayout() override;
void ReceivePostMessage(const std::string& channel,
blink::TransferableMessage message) override;
void MessageSync(bool internal,
Expand All @@ -51,17 +51,13 @@ class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
blink::CloneableMessage arguments) override;
void MessageHost(const std::string& channel,
blink::CloneableMessage arguments) override;
void UpdateDraggableRegions(
std::vector<mojom::DraggableRegionPtr> regions) override;
void SetTemporaryZoomLevel(double level) override;
void DoGetZoomLevel(DoGetZoomLevelCallback callback) override;

base::WeakPtr<ElectronBrowserHandlerImpl> GetWeakPtr() {
base::WeakPtr<ElectronApiIPCHandlerImpl> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}

private:
~ElectronBrowserHandlerImpl() override;
~ElectronApiIPCHandlerImpl() override;

// content::WebContentsObserver:
void WebContentsDestroyed() override;
Expand All @@ -73,11 +69,11 @@ class ElectronBrowserHandlerImpl : public mojom::ElectronBrowser,
const int render_process_id_;
const int render_frame_id_;

mojo::Receiver<mojom::ElectronBrowser> receiver_{this};
mojo::AssociatedReceiver<mojom::ElectronApiIPC> receiver_{this};

base::WeakPtrFactory<ElectronBrowserHandlerImpl> weak_factory_{this};
base::WeakPtrFactory<ElectronApiIPCHandlerImpl> weak_factory_{this};

DISALLOW_COPY_AND_ASSIGN(ElectronBrowserHandlerImpl);
DISALLOW_COPY_AND_ASSIGN(ElectronApiIPCHandlerImpl);
};
} // namespace electron
#endif // SHELL_BROWSER_ELECTRON_BROWSER_HANDLER_IMPL_H_
#endif // SHELL_BROWSER_ELECTRON_API_IPC_HANDLER_IMPL_H_

0 comments on commit d5dd3fb

Please sign in to comment.