Commit f965f3db authored by arthursonzogni's avatar arthursonzogni Committed by Commit Bot

[COOP] access reporting [2/N] Browser -> renderer(s) IPC.

All of this is put behind a flag disabled by default.

This is mostly based on the initial prototype:
https://chromium-review.googlesource.com/c/chromium/src/+/2223934/24

Add the IPC InstallCoopAccessMonitor to the LocalMainFrame interface.
This is called by the browser process whenever an access in between two
windows would be blocked if COOP was enforced.

This is mostly based on the initial prototype:
https://chromium-review.googlesource.com/c/chromium/src/+/2223934/24

COOP access reporting:
[1/N] https://chromium-review.googlesource.com/c/chromium/src/+/2264294
[2/N] this patch.

TBR=mkwst@chromium.org

Bug: chromium:1090273
Change-Id: I366ef78ec5ac59ca9475871928afd05d2e02fddd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2270185Reviewed-by: default avatarArthur Sonzogni <arthursonzogni@chromium.org>
Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Auto-Submit: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#784871}
parent e0553dee
...@@ -69,6 +69,20 @@ RenderFrameHostImpl* GetSourceRfhForCoopReporting( ...@@ -69,6 +69,20 @@ RenderFrameHostImpl* GetSourceRfhForCoopReporting(
return current_rfh; return current_rfh;
} }
base::UnguessableToken GetFrameToken(FrameTreeNode* frame,
SiteInstance* site_instance) {
RenderFrameHostImpl* rfh = frame->current_frame_host();
if (rfh->GetSiteInstance() == site_instance)
return rfh->GetFrameToken();
RenderFrameProxyHost* proxy =
frame->render_manager()->GetRenderFrameProxyHost(site_instance);
if (proxy)
return proxy->GetFrameToken();
return base::UnguessableToken::Null();
}
// Find all the related windows that might try to access the new document in // Find all the related windows that might try to access the new document in
// |frame|, but are in a different virtual browsing context group. // |frame|, but are in a different virtual browsing context group.
std::vector<FrameTreeNode*> CollectOtherWindowForCoopAccess( std::vector<FrameTreeNode*> CollectOtherWindowForCoopAccess(
...@@ -250,22 +264,27 @@ void CrossOriginOpenerPolicyReporter::InstallAccessMonitorsIfNeeded( ...@@ -250,22 +264,27 @@ void CrossOriginOpenerPolicyReporter::InstallAccessMonitorsIfNeeded(
// If the current frame has a reporter, install the access monitors to // If the current frame has a reporter, install the access monitors to
// monitor the accesses between this frame and the other frame. // monitor the accesses between this frame and the other frame.
if (reporter_frame) if (reporter_frame) {
reporter_frame->MonitorAccessesInBetweenWindows(frame, other); reporter_frame->MonitorAccesses(frame, other);
reporter_frame->MonitorAccesses(other, frame);
}
// If the other frame has a reporter, install the access monitors to monitor // If the other frame has a reporter, install the access monitors to monitor
// the accesses between this frame and the other frame. // the accesses between this frame and the other frame.
if (reporter_other) if (reporter_other) {
reporter_other->MonitorAccessesInBetweenWindows(frame, other); reporter_other->MonitorAccesses(frame, other);
reporter_other->MonitorAccesses(other, frame);
}
} }
} }
void CrossOriginOpenerPolicyReporter::MonitorAccessesInBetweenWindows( void CrossOriginOpenerPolicyReporter::MonitorAccesses(
FrameTreeNode* A, FrameTreeNode* accessing_node,
FrameTreeNode* B) { FrameTreeNode* accessed_node) {
DCHECK_NE(A, B); DCHECK_NE(accessing_node, accessed_node);
DCHECK(A->current_frame_host()->coop_reporter() == this || DCHECK(accessing_node->current_frame_host()->coop_reporter() == this ||
B->current_frame_host()->coop_reporter() == this); accessed_node->current_frame_host()->coop_reporter() == this);
// TODO(arthursonzogni): DCHECK same browsing context group. // TODO(arthursonzogni): DCHECK same browsing context group.
// TODO(arthursonzogni): DCHECK different virtual browsing context group. // TODO(arthursonzogni): DCHECK different virtual browsing context group.
...@@ -275,8 +294,20 @@ void CrossOriginOpenerPolicyReporter::MonitorAccessesInBetweenWindows( ...@@ -275,8 +294,20 @@ void CrossOriginOpenerPolicyReporter::MonitorAccessesInBetweenWindows(
// It means all the accessed from the first window are made from documents // It means all the accessed from the first window are made from documents
// inside the same SiteInstance. Only one SiteInstance has to be updated. // inside the same SiteInstance. Only one SiteInstance has to be updated.
// TODO(arthursonzogni): Continue the implementation. Send an IPC toward the RenderFrameHostImpl* accessing_rfh = accessing_node->current_frame_host();
// accessed window. SiteInstance* site_instance = accessing_rfh->GetSiteInstance();
base::UnguessableToken accessed_window_token =
GetFrameToken(accessed_node, site_instance);
if (!accessed_window_token)
return;
mojo::PendingRemote<network::mojom::CrossOriginOpenerPolicyReporter>
remote_reporter;
Clone(remote_reporter.InitWithNewPipeAndPassReceiver());
accessing_rfh->GetAssociatedLocalMainFrame()->InstallCoopAccessMonitor(
accessed_window_token, std::move(remote_reporter));
} }
} // namespace content } // namespace content
...@@ -84,8 +84,10 @@ class CONTENT_EXPORT CrossOriginOpenerPolicyReporter final ...@@ -84,8 +84,10 @@ class CONTENT_EXPORT CrossOriginOpenerPolicyReporter final
const network::CrossOriginOpenerPolicy& coop, const network::CrossOriginOpenerPolicy& coop,
const network::CrossOriginEmbedderPolicy& coep); const network::CrossOriginEmbedderPolicy& coep);
// Install the CoopAccessMonitors in between the two windows |A| and |B|. // Install the CoopAccessMonitors monitoring accesses from |accessing_node|
void MonitorAccessesInBetweenWindows(FrameTreeNode* A, FrameTreeNode* B); // toward |accessed_node|.
void MonitorAccesses(FrameTreeNode* accessing_node,
FrameTreeNode* accessed_node);
// See the class comment. // See the class comment.
StoragePartition* const storage_partition_; StoragePartition* const storage_partition_;
......
...@@ -13,6 +13,7 @@ import "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojo ...@@ -13,6 +13,7 @@ import "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojo
import "services/network/public/mojom/content_security_policy.mojom"; import "services/network/public/mojom/content_security_policy.mojom";
import "services/network/public/mojom/fetch_api.mojom"; import "services/network/public/mojom/fetch_api.mojom";
import "services/network/public/mojom/web_sandbox_flags.mojom"; import "services/network/public/mojom/web_sandbox_flags.mojom";
import "services/network/public/mojom/cross_origin_opener_policy.mojom";
import "skia/public/mojom/skcolor.mojom"; import "skia/public/mojom/skcolor.mojom";
import "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom"; import "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom";
import "third_party/blink/public/mojom/blob/blob.mojom"; import "third_party/blink/public/mojom/blob/blob.mojom";
...@@ -826,6 +827,13 @@ interface LocalMainFrame { ...@@ -826,6 +827,13 @@ interface LocalMainFrame {
// Sent to the main-frame to request performing a zoom-to-find-in-page // Sent to the main-frame to request performing a zoom-to-find-in-page
// based on the rect provided. // based on the rect provided.
ZoomToFindInPageRect(gfx.mojom.Rect rect_in_root_frame); ZoomToFindInPageRect(gfx.mojom.Rect rect_in_root_frame);
// Cross-Origin-Opener-Policy(COOP):
// Check accesses made from this window to |accessed_window|. If this happens,
// a report will be sent to |reporter|.
InstallCoopAccessMonitor(
mojo_base.mojom.UnguessableToken accessed_window,
pending_remote<network.mojom.CrossOriginOpenerPolicyReporter> reporter);
}; };
// Implemented in Browser, this interface defines local-main-frame-specific // Implemented in Browser, this interface defines local-main-frame-specific
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h" #include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_window.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.h" #include "third_party/blink/renderer/bindings/core/v8/v8_window_post_message_options.h"
#include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h" #include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h"
#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document.h"
...@@ -422,6 +425,22 @@ void DOMWindow::PostMessageForTesting( ...@@ -422,6 +425,22 @@ void DOMWindow::PostMessageForTesting(
DoPostMessage(std::move(message), ports, options, source, exception_state); DoPostMessage(std::move(message), ports, options, source, exception_state);
} }
void DOMWindow::InstallCoopAccessMonitor(
LocalFrame* accessing_frame,
mojo::PendingRemote<network::mojom::blink::CrossOriginOpenerPolicyReporter>
pending_reporter) {
CoopAccessMonitor monitor;
DCHECK(accessing_frame->IsMainFrame());
monitor.accessing_main_frame = accessing_frame->GetFrameToken();
// TODO(arthursonzogni): Clean coop_access_monitor_ when a reporter is gone.
// Use mojo::Remote::set_disconnect_handler.
monitor.reporter.Bind(std::move(pending_reporter));
coop_access_monitor_.push_back(std::move(monitor));
}
void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message, void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message,
const MessagePortArray& ports, const MessagePortArray& ports,
const WindowPostMessageOptions* options, const WindowPostMessageOptions* options,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_DOM_WINDOW_H_
#include "services/network/public/mojom/cross_origin_opener_policy.mojom-blink.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/dom/events/event_target.h"
...@@ -12,6 +13,7 @@ ...@@ -12,6 +13,7 @@
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink { namespace blink {
...@@ -130,6 +132,14 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData { ...@@ -130,6 +132,14 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData {
LocalDOMWindow* source, LocalDOMWindow* source,
ExceptionState&); ExceptionState&);
// Cross-Origin-Opener-Policy (COOP):
// Check accesses from |accessing_frame| and his same-origin iframes toward
// this window. If this happens, a report will be sent to |reporter|.
void InstallCoopAccessMonitor(
LocalFrame* accessing_frame,
mojo::PendingRemote<
network::mojom::blink::CrossOriginOpenerPolicyReporter> reporter);
protected: protected:
explicit DOMWindow(Frame&); explicit DOMWindow(Frame&);
...@@ -160,6 +170,16 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData { ...@@ -160,6 +170,16 @@ class CORE_EXPORT DOMWindow : public EventTargetWithInlineData {
// operation has been performed, exposes (confusing) // operation has been performed, exposes (confusing)
// implementation details to scripts. // implementation details to scripts.
bool window_is_closing_; bool window_is_closing_;
// Cross-Origin-Opener-Policy (COOP):
// Check accesses made toward this window from |accessing_main_frame|. If this
// happens a report will sent to |reporter|.
struct CoopAccessMonitor {
base::UnguessableToken accessing_main_frame;
mojo::Remote<network::mojom::blink::CrossOriginOpenerPolicyReporter>
reporter;
};
WTF::Vector<CoopAccessMonitor> coop_access_monitor_;
}; };
} // namespace blink } // namespace blink
......
...@@ -2253,6 +2253,19 @@ void LocalFrame::GetFirstRectForRange(const gfx::Range& range) { ...@@ -2253,6 +2253,19 @@ void LocalFrame::GetFirstRectForRange(const gfx::Range& range) {
} }
#endif #endif
void LocalFrame::InstallCoopAccessMonitor(
const base::UnguessableToken& accessed_window,
mojo::PendingRemote<network::mojom::blink::CrossOriginOpenerPolicyReporter>
reporter) {
blink::Frame* accessed_frame = Frame::ResolveFrame(accessed_window);
// The Frame might have been deleted during the cross-process communication.
if (!accessed_frame)
return;
accessed_frame->DomWindow()->InstallCoopAccessMonitor(this,
std::move(reporter));
}
HitTestResult LocalFrame::HitTestResultForVisualViewportPos( HitTestResult LocalFrame::HitTestResultForVisualViewportPos(
const IntPoint& pos_in_viewport) { const IntPoint& pos_in_viewport) {
IntPoint root_frame_point( IntPoint root_frame_point(
......
...@@ -602,6 +602,11 @@ class CORE_EXPORT LocalFrame final : public Frame, ...@@ -602,6 +602,11 @@ class CORE_EXPORT LocalFrame final : public Frame,
void GetCharacterIndexAtPoint(const gfx::Point& point) final; void GetCharacterIndexAtPoint(const gfx::Point& point) final;
void GetFirstRectForRange(const gfx::Range& range) final; void GetFirstRectForRange(const gfx::Range& range) final;
#endif #endif
void InstallCoopAccessMonitor(
const base::UnguessableToken& accessed_window,
mojo::PendingRemote<
network::mojom::blink::CrossOriginOpenerPolicyReporter> reporter)
final;
SystemClipboard* GetSystemClipboard(); SystemClipboard* GetSystemClipboard();
RawSystemClipboard* GetRawSystemClipboard(); RawSystemClipboard* GetRawSystemClipboard();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment