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

[COOP] Access reporting with 2 reporters.

A regression has been introduced by [1]:
```
[COOP] access reporting: Clear old CoopAccessMonitor.
https://chromium-review.googlesource.com/c/chromium/src/+/2408752
```

Instead of accumulating the CoopAccessMonitor for the same pair of
(accessing, accessed) window, it limited it to one and kept only the
most recent one.

This is an issue, because both the accessing and the accessed window
might have a reporter defined. We must keep both for supporting sending
reports toward both.

This patch adds regressions tests.

Bug: 1090273
Change-Id: I2a3aa7f26458db820d3383245c60c5f3f917acd3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2414308Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Commit-Queue: Arthur Sonzogni <arthursonzogni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808323}
parent a1539502
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "third_party/blink/renderer/core/frame/dom_window.h" #include "third_party/blink/renderer/core/frame/dom_window.h"
#include <algorithm>
#include <memory> #include <memory>
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
...@@ -463,11 +464,20 @@ void DOMWindow::InstallCoopAccessMonitor( ...@@ -463,11 +464,20 @@ void DOMWindow::InstallCoopAccessMonitor(
// The new documents will still be part of a different virtual browsing // The new documents will still be part of a different virtual browsing
// context group, however the new COOPAccessMonitor might now contain updated // context group, however the new COOPAccessMonitor might now contain updated
// URLs. // URLs.
DisconnectCoopAccessMonitor(monitor.accessing_main_frame); //
// There are up to 2 CoopAccessMonitor for the same access, because it can be
// reported to the accessing and the accessed window at the same time.
for (CoopAccessMonitor& old : coop_access_monitor_) {
if (old.accessing_main_frame == monitor.accessing_main_frame &&
network::IsAccessFromCoopPage(old.report_type) ==
network::IsAccessFromCoopPage(monitor.report_type)) {
old = std::move(monitor);
return;
}
}
coop_access_monitor_.push_back(std::move(monitor));
// Any attempts to access |this| window from |accessing_main_frame| will now // Any attempts to access |this| window from |accessing_main_frame| will now
// trigger reports (network, ReportingObserver, Devtool). // trigger reports (network, ReportingObserver, Devtool).
coop_access_monitor_.push_back(std::move(monitor));
} }
// Check if the accessing context would be able to access this window if COOP // Check if the accessing context would be able to access this window if COOP
......
<title>
Both the openee and the opener have a COOP reporter. The report are sent to
both side.
</title>
<meta name=timeout content=long>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src="/common/utils.js"></script>
<script src="../resources/dispatcher.js"></script>
<script src="../resources/try-access.js"></script>
<script>
const directory = "/html/cross-origin-opener-policy/reporting";
const executor_path = directory + "/resources/executor.html?pipe=";
const origin_opener = get_host_info().HTTPS_ORIGIN;
const origin_openee = get_host_info().HTTPS_REMOTE_ORIGIN;
const coep_header = '|header(Cross-Origin-Embedder-Policy,require-corp)';
let escapeComma = url => url.replace(/,/g, '\\,');
let genericSetup = async function(test) {
// The test window.
const this_window_token = token();
// The "opener" window. This has COOP and a reporter.
const opener_report_token= token();
const opener_token = token();
const opener_reportTo = reportToHeaders(opener_report_token);
const opener_url = origin_opener+ executor_path + opener_reportTo.header +
opener_reportTo.coopReportOnlySameOriginHeader + coep_header +
`&uuid=${opener_token}`;
// The "openee" window. This has COOP and a reporter.
const openee_report_token= token();
const openee_token = token();
const openee_reportTo = reportToHeaders(openee_report_token);
const openee_url = origin_openee + executor_path + openee_reportTo.header +
openee_reportTo.coopReportOnlySameOriginHeader + coep_header +
`&uuid=${openee_token}`;
// Cleanup at the end of the test.
test.add_cleanup(() => {
send(openee_token, 'window.close()');
send(opener_token, 'window.close()');
});
// 1. Spawn the opener and the openee windows.
window.open(opener_url);
send(opener_token, `
openee = window.open('${escapeComma(openee_url)}');
`);
// 2. Wait for both to be loaded.
send(openee_token, `send('${this_window_token}', 'ACK');`);
assert_equals(await receive(this_window_token), 'ACK');
return [
this_window_token,
opener_token, opener_report_token, opener_url,
openee_token, openee_report_token, openee_url,
];
}
let assert_generic_coop_report = function(report) {
assert_equals(report.type, "coop");
assert_equals(report.body.disposition, "reporting");
assert_equals(report.body.effectivePolicy, "same-origin-plus-coep");
assert_equals(report.body.property, "blur");
}
promise_test(async test => {
let [
this_window_token,
opener_token, opener_report_token, opener_url,
openee_token, openee_report_token, openee_url,
] = await genericSetup(test);
send(opener_token, `tryAccess(openee);`);
let report_opener =
await receiveReport(opener_report_token, "access-from-coop-page-to-openee")
let report_openee =
await receiveReport(openee_report_token, "access-to-coop-page-from-opener")
assert_not_equals(report_openee, "timeout", "Report openee not received");
assert_not_equals(report_opener, "timeout", "Report opener not received");
assert_generic_coop_report(report_openee);
assert_generic_coop_report(report_opener);
assert_equals(report_opener.url, opener_url.replace(/"/g, '%22'));
assert_equals(report_openee.url, openee_url.replace(/"/g, '%22'));
assert_source_location_found(report_opener);
assert_source_location_missing(report_openee);
}, "Access from opener")
promise_test(async test => {
let [
this_window_token,
opener_token, opener_report_token, opener_url,
openee_token, openee_report_token, openee_url,
] = await genericSetup(test);
send(openee_token, `tryAccess(opener);`);
let report_opener =
await receiveReport(opener_report_token, "access-to-coop-page-from-openee")
let report_openee =
await receiveReport(openee_report_token, "access-from-coop-page-to-opener")
assert_not_equals(report_openee, "timeout", "Report openee not received");
assert_not_equals(report_opener, "timeout", "Report opener not received");
assert_generic_coop_report(report_openee);
assert_generic_coop_report(report_opener);
assert_equals(report_opener.url, opener_url.replace(/"/g, '%22'));
assert_equals(report_openee.url, openee_url.replace(/"/g, '%22'));
assert_source_location_missing(report_opener);
assert_source_location_found(report_openee);
}, "Access from openee")
</script>
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