Skip to content

Commit

Permalink
[COOP] access reporting [1/N] List the accesses.
Browse files Browse the repository at this point in the history
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

This patches list all the potential accesses to be checked and reported.
The CrossOriginOpenerPolicyReporter is preparing itself to install all
the CoopAccessMonitor to the renderer(s), but It doesn't send them for
now.

To write a meaningful patch, this will need accesses to COOP-Report-Only
headers and the virtual browsing context group.

Explainer [WIP]:
https://github.com/camillelamy/explainers/blob/master/coop_reporting.md

Specification [WIP]:
whatwg/html#5518

Tests [WIP]:
https://wpt.fyi/results/html/cross-origin-opener-policy/access-reporting

Doc [WIP]:
https://docs.google.com/document/d/1H8Be0w27fKPXKqyuJj9oEqIJEjB9Rw5AP3x-w-Fx2Zg/edit?usp=sharing

Bug: chromium:1090273
Change-Id: I5d4c613a671f99ba15b4b174431d8d3ddeaa44c6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2264294
Reviewed-by: Camille Lamy <[email protected]>
Reviewed-by: Pâris Meuleman <[email protected]>
Commit-Queue: Arthur Sonzogni <[email protected]>
Cr-Commit-Position: refs/heads/master@{#783972}
  • Loading branch information
ArthurSonzogni authored and Commit Bot committed Jun 30, 2020
1 parent d43cb4a commit 59b5ac9
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
3 changes: 3 additions & 0 deletions content/browser/frame_host/render_frame_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8211,6 +8211,9 @@ bool RenderFrameHostImpl::DidCommitNavigationInternal(

RecordCrossOriginIsolationMetrics(this);

CrossOriginOpenerPolicyReporter::InstallAccessMonitorsIfNeeded(
frame_tree_node_);

return true;
}

Expand Down
92 changes: 92 additions & 0 deletions content/browser/net/cross_origin_opener_policy_reporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
#include "base/values.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_frame_proxy_host.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/storage_partition.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "url/origin.h"

namespace content {

Expand Down Expand Up @@ -64,6 +69,32 @@ RenderFrameHostImpl* GetSourceRfhForCoopReporting(
return current_rfh;
}

// Find all the related windows that might try to access the new document in
// |frame|, but are in a different virtual browsing context group.
std::vector<FrameTreeNode*> CollectOtherWindowForCoopAccess(
FrameTreeNode* frame) {
DCHECK(frame->IsMainFrame());
SiteInstance* site_instance = frame->current_frame_host()->GetSiteInstance();

std::vector<FrameTreeNode*> out;
for (WebContentsImpl* wc : WebContentsImpl::GetAllWebContents()) {
RenderFrameHostImpl* rfh = wc->GetMainFrame();

// Filters out windows from a different browsing context group.
if (!rfh->GetSiteInstance()->IsRelatedSiteInstance(site_instance))
continue;

// TODO(arthursonzogni): Filter out window from the same virtual browsing
// context group.
FrameTreeNode* ftn = rfh->frame_tree_node();
if (ftn == frame)
continue;

out.push_back(ftn);
}
return out;
}

} // namespace

CrossOriginOpenerPolicyReporter::CrossOriginOpenerPolicyReporter(
Expand Down Expand Up @@ -187,4 +218,65 @@ GURL CrossOriginOpenerPolicyReporter::GetNextDocumentUrlForReporting(
return GURL();
}

// static
void CrossOriginOpenerPolicyReporter::InstallAccessMonitorsIfNeeded(
FrameTreeNode* frame) {
if (!frame->IsMainFrame())
return;

// The function centralize all the CoopAccessMonitor being added. Checking the
// flag here ensures the feature to be properly disabled everywhere.
if (!base::FeatureList::IsEnabled(
network::features::kCrossOriginOpenerPolicyAccessReporting)) {
return;
}

// TODO(arthursonzogni): It is too late to update the SiteInstance of the new
// document. Ideally, this should be split into two parts:
// - CommitNavigation: Update the new document's SiteInstance.
// - DidCommitNavigation: Update the other SiteInstances.

// Find all the related windows that might try to access the new document,
// but are from a different virtual browsing context group.
std::vector<FrameTreeNode*> other_main_frames =
CollectOtherWindowForCoopAccess(frame);

CrossOriginOpenerPolicyReporter* reporter_frame =
frame->current_frame_host()->coop_reporter();

for (FrameTreeNode* other : other_main_frames) {
CrossOriginOpenerPolicyReporter* reporter_other =
other->current_frame_host()->coop_reporter();

// If the current frame has a reporter, install the access monitors to
// monitor the accesses between this frame and the other frame.
if (reporter_frame)
reporter_frame->MonitorAccessesInBetweenWindows(frame, other);

// If the other frame has a reporter, install the access monitors to monitor
// the accesses between this frame and the other frame.
if (reporter_other)
reporter_other->MonitorAccessesInBetweenWindows(frame, other);
}
}

void CrossOriginOpenerPolicyReporter::MonitorAccessesInBetweenWindows(
FrameTreeNode* A,
FrameTreeNode* B) {
DCHECK_NE(A, B);
DCHECK(A->current_frame_host()->coop_reporter() == this ||
B->current_frame_host()->coop_reporter() == this);
// TODO(arthursonzogni): DCHECK same browsing context group.
// TODO(arthursonzogni): DCHECK different virtual browsing context group.

// Accesses are made either from the main frame or its same-origin iframes.
// Accesses from the cross-origin ones aren't reported.
//
// It means all the accessed from the first window are made from documents
// inside the same SiteInstance. Only one SiteInstance has to be updated.

// TODO(arthursonzogni): Continue the implementation. Send an IPC toward the
// accessed window.
}

} // namespace content
9 changes: 9 additions & 0 deletions content/browser/net/cross_origin_opener_policy_reporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace content {

class FrameTreeNode;
class StoragePartition;
class RenderFrameHostImpl;

Expand Down Expand Up @@ -62,6 +63,11 @@ class CONTENT_EXPORT CrossOriginOpenerPolicyReporter final
const std::vector<GURL>& redirect_chain,
const GlobalFrameRoutingId& initiator_routing_id);

// For every other window in the same browsing context group, but in a
// different virtual browsing context group, install the necessary
// CoopAccessMonitor. The first window is identified by |node|.
static void InstallAccessMonitorsIfNeeded(FrameTreeNode* node);

void Clone(
mojo::PendingReceiver<network::mojom::CrossOriginOpenerPolicyReporter>
receiver) override;
Expand All @@ -78,6 +84,9 @@ class CONTENT_EXPORT CrossOriginOpenerPolicyReporter final
const network::CrossOriginOpenerPolicy& coop,
const network::CrossOriginEmbedderPolicy& coep);

// Install the CoopAccessMonitors in between the two windows |A| and |B|.
void MonitorAccessesInBetweenWindows(FrameTreeNode* A, FrameTreeNode* B);

// See the class comment.
StoragePartition* const storage_partition_;
GURL source_url_;
Expand Down

0 comments on commit 59b5ac9

Please sign in to comment.